#!/usr/bin/env python
#
#Ultimate Theme Manager
#Manage any application's theme from one application.
#See http://ultimate-theme-manager.googlecode.com for details
#Or sharkbaitbobby+utm@gmail.com

#Import stuff
import pygtk #Needed for gtk
pygtk.require("2.0") #Needed for gtk
import gtk #Needed for gtk
import pango #Needed for making fonts bigger
import os #Needed for some stuff
import subprocess #For calling things without waiting
import gconf #For finding out the default browser and maybe terminal
import tarfile #For importing theme types
from xml.dom.ext.reader.Sax2 import FromXml #For getting the an xml document
from xml.dom.ext import PrettyPrint #For writing a changed xml document
import sys #For sys.stdout
import time #For repositories
import gobject #For lists
the_pope = "catholic"
catholic = "catholic"

if "--debug" in sys.argv or "-d" in sys.argv:
	sys.stdout2 = sys.stdout
	sys.stdout = open('%s/Desktop/utm.txt' % self.homepath,'w+')

class mainWindow:
	"""This is the main window for UTM. Just do mainWindow(), if I have the syntax correct."""
	#This function will execute when a mainWindow instance is created.
	def __init__(self):
		#Find out the home path (usually /home/$USER (aka $HOME), but open() doesn't support bash variables) :(
		for self.x in os.environ.items():
			if self.x[0]=="HOME":
				self.homepath = self.x[1]
		
		#Set up the .utm directory for this user.
		if not ".utm" in os.listdir(self.homepath):
			os.system('mkdir %s/.utm' % self.homepath)
			os.system('ln -s /usr/share/ultimate-theme-manager/logo.png %s/.utm/logo.png' % self.homepath)
			os.system('ln -s /usr/share/ultimate-theme-manager/logo24.png %s/.utm/logo24.png' % self.homepath)
			os.system('ln -s /usr/share/ultimate-theme-manager/logo16.png %s/.utm/logo16.png' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/themes.xml %s/.utm/themes.xml' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/types.xml %s/.utm/types.xml' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/sources.xml %s/.utm/sources.xml' % self.homepath)
			os.system('mkdir %s/.utm/sources' % self.homepath)
			os.system('mkdir %s/.utm/sources/downloads' % self.homepath)
			#This section is for my default list. Feel free to change or remove it if you wish.
			os.system('mkdir %s/.utm/sources/09f911039d74e35bd84156c5635688c0' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/imported.xml %s/.utm/sources/09f911039d74e35bd84156c5635688c0/imported.xml' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/list.xml %s/.utm/sources/09f911039d74e35bd84156c5635688c0/list.xml' % self.homepath)
			os.system('echo 1 > %s/.utm/sources/09f911039d74e35bd84156c5635688c0/timestamp' % self.homepath)
			#End that section
			os.system('mkdir %s/.utm/sources/downloads/images' % self.homepath)
			os.system('cp /usr/share/ultimate-theme-manager/images.xml %s/.utm/souces/images.xml' % self.homepath)
			os.system('mkdir %s/.utm/theme-files' % self.homepath)
			os.system('mkdir %s/.utm/themes' % self.homepath)
			os.system('mkdir %s/.utm/type-files' % self.homepath)
			os.system('mkdir %s/.utm/types' % self.homepath)
		
		#Create the gtk window, resize it, and title it.
		self.w=gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.w.set_size_request(700, 500)
		self.w.set_title("Ultimate Theme Manager")
		self.w.connect("destroy", self.destroy)
		self.wimg1 = gtk.gdk.pixbuf_new_from_file("%s/.utm/logo.png" % self.homepath)
		self.wimg2 = gtk.gdk.pixbuf_new_from_file("%s/.utm/logo24.png" % self.homepath)
		self.wimg3 = gtk.gdk.pixbuf_new_from_file("%s/.utm/logo16.png" % self.homepath)
		self.w.set_icon_list(self.wimg1,self.wimg2,self.wimg3)
		
		#Get the xmlData instance. (xml)
		self.xml = xmlData()
		
		#self.repositories is a Repositories() instance, used for getting info about the repositories and their themes/types
		self.repositories = Repositories()
		
		#Now all of the left pane will go in a gtk.ScrolledWindow(), with automatic scrollbars.
		self.scrolled = gtk.ScrolledWindow()
		self.scrolled.set_size_request(350,False)
		self.scrolled.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.scrolled.show()
		
		#Now for the right side of the pane.
		#self.right_window is the scrolledwindow
		#self.right_pane is the widget that is in it
		#I don't even know if the Loading message will appear but it's better than nothing
		self.right_pane = gtk.Label("Loading...\n\n(Please Wait)")
		self.right_pane.show()
		self.right_vbox = gtk.VBox(False,10)
		self.right_vbox.pack_start(self.right_pane,False,True)
		self.right_vbox.show()
		self.right_window = gtk.ScrolledWindow()
		self.right_window.set_size_request(325,500)
		self.right_window.add_with_viewport(self.right_vbox)
		self.right_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.right_window.show()
		
		#Remove the duplicate themes. Keep the first one.
		self.removeThemeDupes()
		
		#Call the viewTypesAndThemes() function which will "index" the themes and types, then display them as they should be displayed
		#This will also "change" the right pane to "Select a theme or theme type on the left... You have x themes... etc.
		self.current_state = "list"
		self.changing_state = False
		self.viewTypesAndThemes()
		
		#Now for the pane, that will divide the left and the right at adjustable lengths.
		self.pane = gtk.HPaned()
		self.pane.add1(self.scrolled)
		self.pane.add2(self.right_window)
		self.pane.show()
		
		#Now create the four buttons for help, about, refresh, browse, and close.
		self.help_button = gtk.Button(stock=gtk.STOCK_HELP)
		self.help_button.connect("clicked",self.help)
		self.help_button.show()
		self.more = False
		self.more_button = gtk.Button("More",stock=gtk.STOCK_ADD)
		self.more_button.connect("clicked",lambda w:self.toggleMore())
		self.more_button.get_children()[0].get_children()[0].get_children()[1].set_text("More")
		self.more_button.show()
		self.less_button = gtk.Button("Less",stock=gtk.STOCK_REMOVE)
		self.less_button.connect("clicked",lambda w:self.toggleMore())
		self.less_button.get_children()[0].get_children()[0].get_children()[1].set_text("Less")
		self.about_button = gtk.Button(stock=gtk.STOCK_ABOUT)
		self.about_button.connect("clicked",self.about)
		self.about_button.show()
		self.refresh_button = gtk.Button(stock=gtk.STOCK_REFRESH)
		self.refresh_button.connect("clicked",lambda w: self.refresh())
		self.refresh_button.show()
		self.browse_button = gtk.Button(stock=gtk.STOCK_OPEN)
		self.browse_button.connect("clicked",lambda w: self.browse())
		self.browse_button.show()
		self.close_button = gtk.Button(stock=gtk.STOCK_CLOSE)
		self.close_button.connect("clicked",self.destroy)
		self.close_button.show()
		
		#Create a button for getting themes
		self.get_themes = gtk.ToggleButton("Get Themes")
		self.get_themes.connect("toggled",lambda w:self.getThemes())
		self.get_themes.show()
		
		#Now create a button for getting theme types
		self.get_types = gtk.ToggleButton("Get Types")
		self.get_types.connect("toggled",lambda w:self.getTypes())
		self.get_types.show()
		
		#Now create a ToggleButton for toggling if the sources list is shown
		self.view_sources = gtk.ToggleButton("View Sources")
		self.view_sources.connect("toggled",lambda w:self.viewSources())
		self.view_sources.show()
		
		#Now for a bbox which will hold the help, about, refresh, browse, and close buttons
		self.bbox = gtk.HButtonBox()
		self.bbox.set_layout(gtk.BUTTONBOX_EDGE)
		self.bbox.add(self.help_button)
		self.bbox.add(self.about_button)
		self.bbox.add(self.more_button)
		self.bbox.add(self.less_button)
		self.bbox.add(self.browse_button)
		self.bbox.add(self.close_button)
		self.bbox.show()
		
		#Create a second row of buttons for View Sources, Get Themes, Get Types, and Refresh
		self.bbox2 = gtk.HButtonBox()
		self.bbox2.set_layout(gtk.BUTTONBOX_EDGE)
		self.bbox2.add(self.view_sources)
		self.bbox2.add(self.get_themes)
		self.bbox2.add(self.get_types)
		self.bbox2.add(self.refresh_button)
		
		#Now for an hbox, which will contain the filter entry widget, and a X button, which will clear the filter
		self.filter_table = gtk.Table(1,2)
		self.filter_entry = gtk.Entry()
		self.filter_entry.set_text("Filter...")
		self.filter_entry.connect("button-press-event",lambda w, e: self.clearFilter(w.get_text()))
		self.filter_entry.connect("changed", lambda w: self.filterList(w.get_text()))
		self.filter_entry.show()
		self.filter_clear = gtk.Button(stock=gtk.STOCK_CLOSE)
		self.filter_clear.get_children()[0].get_children()[0].get_children()[1].destroy()
		self.filter_clear.connect("clicked",lambda w: self.clearFilter(self.filter_entry.get_text(),True))
		self.filter_clear.show()
		self.filter_table.attach(self.filter_clear,0,1,0,1,xoptions=gtk.SHRINK,ypadding=0)
		self.filter_table.attach(self.filter_entry,1,2,0,1,ypadding=0)
		self.filter_table.show()
		
		#Now for a vbox which will hold EVERYTHING.
		self.main_vbox = gtk.VBox(False,5)
		self.main_vbox.pack_end(self.bbox2,False,True)
		self.main_vbox.pack_end(self.bbox,False,True)
		self.main_vbox.pack_end(self.pane,True,True)
		self.main_vbox.pack_end(self.filter_table,False,True)
		self.main_vbox.show()
		
		#Now the main window will add the vbox to it
		#And then show the window, and FINALLY, do gtk.main()
		self.w.add(self.main_vbox)
		self.w.show()
		gtk.main()
	
	#This function will toggle the second row of buttons
	def toggleMore(self):
		if self.more:
			self.bbox2.hide()
			self.more = False
			self.less_button.hide()
			self.more_button.show()
		else:
			self.bbox2.show()
			self.more = True
			self.more_button.hide()
			self.less_button.show()
	
	#View the list of themes from repositories
	def getThemes(self):
		
		#Has to do with changing the current view (get types, view sources, etc.)
		if self.current_state == "get_themes":
			if self.changing_state==False:
				self.viewTypesAndThemes()
		else:
			if self.current_state == "get_types":
				self.changing_state = True
				self.get_types.set_active(False)
			elif self.current_state == "view_sources":
				self.changing_state = True
				self.view_sources.set_active(False)
			self.current_state = "get_themes"
			self.changing_state = False
			self.filter_table.hide()
			try:
				self.vbox.destroy()
			except:
				pass
			
			#self.vbox is the main vbox for the left pane
			self.vbox = gtk.VBox(False)
			self.vbox.show()
			self.scrolled.add_with_viewport(self.vbox)
			
			#Get list of themes from repositories, number of themes, and number of sources with themes
			self.view1_list = self.repositories.getThemes()
			self.view1_num_themes = len(self.view1_list)
			self.view1_num_theme_sources = 0
			
			#This part actually gets the number of sources with themes
			for self.view1_x in self.repositories.doc.documentElement.getElementsByTagName('source'):
				if self.repositories.getAttribute(self.view1_x,'type')=="theme" or self.repositories.getAttribute(self.view1_x,'type')=="both":
					self.view1_num_theme_sources = (self.view1_num_theme_sources+1)
			
			#Create the treeview, liststore, etc for the list!
			
			#First, the liststore and treeview
			self.view1_liststore = gtk.ListStore(gtk.gdk.Pixbuf,str)
			self.view1_treeview = gtk.TreeView(self.view1_liststore)
			
			#pixbuf renderer and text renderer for first and second columns, respectively
			self.view1_pixbufrenderer = gtk.CellRendererPixbuf()
			self.view1_textrenderer = gtk.CellRendererText()

			#the columns for image and information, respectively
			self.view1_column0 = gtk.TreeViewColumn("Image")
			self.view1_column1 = gtk.TreeViewColumn("Information")
			
			#Add the pixbuf renderer to column 0 (for screenshot/logo), and add the pixbuf option
			self.view1_column0.pack_start(self.view1_pixbufrenderer,True)
			self.view1_column0.add_attribute(self.view1_pixbufrenderer,'pixbuf',0)
			
			#Now add the text renderer to column 1 for information, and markup option (wow pango is awesome!)
			self.view1_column1.pack_start(self.view1_textrenderer,True)
			self.view1_column1.add_attribute(self.view1_textrenderer,'markup',1)
			
			#Now add the image column then the text column to the treeview
			self.view1_treeview.append_column(self.view1_column0)
			self.view1_treeview.append_column(self.view1_column1)
			
			#Now connect() the treeview for when a row is selected
			self.view1_get_selection = self.view1_treeview.get_selection()
			#You are not expected to understand this next line. It just changes the right pane on selecting a row
			self.view1_get_selection.connect("changed",lambda w: self.getThemesPane(self.view1_list[self.view1_liststore[w.get_selected()[1]].path[0]]))
			
			#Now show the treeview, and pack_start it to the left pane
			self.view1_treeview.show()
			self.vbox.pack_start(self.view1_treeview)
			
			#Go through each theme in the list
			for self.view1_x in self.view1_list:
				
				#Check if the user has the theme type of this theme
				if self.view1_x[self.repositories.THEME_TYPE] in self.typeplnames:
					#Get the logo if there is one, and if not then get the utm logo. TODO: get stock dialog question mark
					if self.view1_x[self.repositories.THEME_SCREENSHOT] is not None:
						if self.view1_x[self.repositories.THEME_SCREENSHOT][0]!="/":
							self.view1_pixbuf = gtk.gdk.pixbuf_new_from_file(\
							self.repositories.getImagePath(self.view1_x[self.repositories.THEME_SCREENSHOT]))
						else:
							self.view1_pixbuf = gtk.gdk.pixbuf_new_from_file(self.view1_x[self.repositories.THEME_SCREENSHOT])
						
						#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
						self.view1_w = self.view1_pixbuf.get_width()
						self.view1_h = self.view1_pixbuf.get_height()
						if self.view1_w==self.view1_h:
							self.view1_pixbuf = self.view1_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
						else:
							self.view1_pixbuf = self.view1_pixbuf.scale_simple(48,int(self.view1_h*(float(self.view1_h)/float(self.view1_w))),gtk.gdk.INTERP_BILINEAR)
						
					else:
						self.view1_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
					
					#Create the string that has the title and credits. TODO: Add sort by and second information (# downloads, credits, type)
					self.view1_textview = "<big><b>%s</b></big>\n<i>%s</i>" % (\
					self.view1_x[self.repositories.THEME_NAME], \
					"%s Theme" % self.typeslist[self.typeplnames.index(self.view1_x[self.repositories.THEME_TYPE])].getShortName())
					
					#Append the information to the liststore, which will be displayed by the treeview
					self.view1_liststore.append([self.view1_pixbuf, self.view1_textview])
			
			#Now create a label for the right pane, set line wrap to true (doesn't really work :/), show() it, and put it in the right pane
			self.view1_right_pane = gtk.Label("\n\n\n\nYou can download %s theme%s from %s source%s.\n\nSelect a theme from the list on the left\nto view more information about it here." % (self.view1_num_themes, self.isNot1(self.view1_num_themes), self.view1_num_theme_sources, self.isNot1(self.view1_num_theme_sources)))
			self.view1_right_pane.set_line_wrap(True)
			self.view1_right_pane.show()
			self.replaceRightPane(self.view1_right_pane)
	
	#This function takes a list from Repositories which contains info about a theme from a repository and puts it in the right pane
	def getThemesPane(self,theme):
		#This method/function owns self.viewtp_*
		#Create the table that everything will go into and show() it
		self.viewtp_table = gtk.Table(5,2)
		self.viewtp_table.show()
		
		#Create the gtk.Image() that has the screenshot of the theme, or if there is none then a stock question mark
		if theme[self.repositories.THEME_SCREENSHOT] is not None:
			self.viewtp_img = gtk.Image()
			if theme[self.repositories.THEME_SCREENSHOT][0] != "/":
				self.viewtp_img.set_from_file(self.repositories.getImagePath(theme[self.repositories.THEME_SCREENSHOT]))
			else:
				self.viewtp_img.set_from_file(theme[self.repositories.THEME_SCREENSHOT])
			self.viewtp_img.show()
		else:
			self.viewtp_img = gtk.Image()
			self.viewtp_img.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
			self.viewtp_img.show()
		
		#Create the label for the theme name
		self.viewtp_name = gtk.Label(theme[self.repositories.THEME_NAME])
		self.viewtp_name.modify_font(pango.FontDescription('bold 16'))
		self.viewtp_name.set_line_wrap(True)
		self.viewtp_name.show()
		
		#Create the label for credits
		self.viewtp_credits = gtk.Label(theme[self.repositories.THEME_CREDITS])
		self.viewtp_credits.modify_font(pango.FontDescription('italic'))
		self.viewtp_credits.set_line_wrap(True)
		self.viewtp_credits.show()
		
		#Create the label for what type of theme it is
		self.viewtp_type = gtk.Label("%s Theme" % self.typeslist[self.typeplnames.index(theme[self.repositories.THEME_TYPE])].getShortName())
		self.viewtp_type.show()
		
		#Create the label that says what repository the theme is from.
		self.viewtp_source = gtk.Label("From the %s repository" % self.repositories.getRepoAttribute(theme[self.repositories.THEME_SOURCE_ID],'name'))
		self.viewtp_source.modify_font(pango.FontDescription('10'))
		self.viewtp_source.show()
		
		#Create a label for the description, if there is one. attach() it now.
		if theme[self.repositories.THEME_DESCRIPTION] is not None:
			self.viewtp_desc = gtk.Label(theme[self.repositories.THEME_DESCRIPTION])
			self.viewtp_desc.set_line_wrap(True)
			self.viewtp_desc.show()
			self.viewtp_desc_window = gtk.ScrolledWindow()			self.viewtp_desc_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)			self.viewtp_desc_window.add_with_viewport(self.viewtp_desc)
			self.viewtp_desc_window.show()
			self.viewtp_table.attach(self.viewtp_desc_window,0,2,5,6)
		
		#Download button to, well, download the theme
		self.viewtp_download = gtk.Button("Download",stock=gtk.STOCK_GO_DOWN)
		self.viewtp_download.connect("clicked",lambda w: self.downloadTheme(\
		theme[self.repositories.THEME_URL],\
		theme[self.repositories.THEME_TYPE],\
		theme[self.repositories.THEME_SOURCE_ID]))
		self.viewtp_download.get_children()[0].get_children()[0].get_children()[1].set_text("Download")
		self.viewtp_download.show()
		
		#Attach everything to the table
		self.viewtp_table.attach(self.viewtp_img,0,2,0,1)
		self.viewtp_table.attach(self.viewtp_name,0,2,1,2)
		self.viewtp_table.attach(self.viewtp_credits,0,2,2,3,xoptions=gtk.SHRINK)
		self.viewtp_table.attach(self.viewtp_type,0,2,3,4,xoptions=gtk.SHRINK)
		self.viewtp_table.attach(self.viewtp_source,0,2,4,5,xoptions=gtk.SHRINK)
		self.viewtp_table.attach(self.viewtp_download,0,2,6,7,xoptions=gtk.SHRINK)
		
		#Now put the table in the right pane
		self.replaceRightPane(self.viewtp_table)
	
	#This function downloads the theme specified by url, and imports it as a theme of type plname
	#Not really sure where "drt" came from, oh well...
	def downloadTheme(self,url,plname,sourceid):
		
		#Download the theme file
		os.system('wget -nv -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 --output-document=%s/.utm/sources/downloads/%s %s' % (self.homepath, url.split('/')[-1:][0], url))
		
		if True:
			#try to open the downloaded file, if failure then an exception will be raised and a dialog will be made
			self.drt_fp = open('%s/.utm/sources/downloads/%s' % (self.homepath, url.split('/')[-1:][0]),'r')
			self.drt_fp.close()
			
			#import the theme
			self.addTheme('%s/.utm/sources/downloads/%s' % (self.homepath, url.split('/')[-1:][0]),plname)
			
			#Parse the url a bit to get what the theme type should have named the theme (replace .tar.gz with .xml at the end (and bz2) ~)
			self.drt_url = url.split('/')[-1:][0]
			if (self.drt_url.split('.')[-2]=="tar" and self.drt_url.split('.')[-1]=="gz") or (self.drt_url.split('.')[-2]=="tar" and self.drt_url.split('.')[-1]=="bz2"):
				self.drt_new_filename = ".".join(self.drt_url.split('.')[:-2])+".xml"
			else:
				self.drt_new_filename = ".".join(self.drt_url.split('.')[:-1])+".xml"
			
			#Open the new theme file to get information about it (version)
			self.drt_new_fp = open('%s/.utm/themes/%s/%s' % (self.homepath, plname, self.drt_new_filename),'r')
			self.drt_new_doc = FromXml(self.drt_new_fp.read())
			self.drt_new_fp.close()
			
			#open the imported list from the source, create an xml document from it, and close the file. this will add info about the recently
			#downloaded and imported theme
			self.drt_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, sourceid),'r')
			self.drt_doc = FromXml(self.drt_fp.read())
			self.drt_fp.close()
			
			#<item>\n<type>\ntheme</type>\n<theme-type>plname</theme-type>\n<filename>filename</filename>\n</item>
			self.drt_element0 = self.drt_doc.createElement('item')
			self.drt_element1 = self.drt_doc.createElement('type')
			self.drt_element2 = self.drt_doc.createElement('theme-type')
			self.drt_element3 = self.drt_doc.createElement('filename')
			self.drt_element4 = self.drt_doc.createElement('version')
			
			self.drt_textnode1 = self.drt_doc.createTextNode('theme')
			self.drt_textnode2 = self.drt_doc.createTextNode(plname)
			self.drt_textnode3 = self.drt_doc.createTextNode(self.drt_new_filename)
			self.drt_textnode4 = self.drt_doc.createTextNode(str(self.repositories.getAttribute(self.drt_doc.documentElement,'version')))
			
			self.drt_element1.appendChild(self.drt_textnode1)
			self.drt_element2.appendChild(self.drt_textnode2)
			self.drt_element3.appendChild(self.drt_textnode3)
			self.drt_element4.appendChild(self.drt_textnode4)
			
			self.drt_element0.appendChild(self.drt_element1)
			self.drt_element0.appendChild(self.drt_element2)
			self.drt_element0.appendChild(self.drt_element3)
			self.drt_element0.appendChild(self.drt_element4)
			
			#Append self.drt_element0 to the main doc, then prettyprint it.
			self.drt_doc.documentElement.appendChild(self.drt_element0)
			self.drt_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, sourceid),'w')
			PrettyPrint(self.drt_doc,self.drt_fp)
			self.drt_fp.close()
			
			#Now refresh, which will display get themes again, but this time the recently downloaded theme won't be there!
			self.refresh()
		
		else:
			#There was an error in downloading the file. So boring. Make dialog.
			self.simpleNetworkDialog('theme')
	
	#Alright for the record when I changed getThemes to getTypes, I was tired and hungry, so if I thought it was good, and committed,
	#You know why everything's messed up
	#View the list of themes from repositories
	def getTypes(self):
		
		#Has to do with changing the current view (get types, view sources, etc.)
		if self.current_state == "get_types":
			if self.changing_state==False:
				self.viewTypesAndThemes()
		else:
			if self.current_state == "get_themes":
				self.changing_state = True
				self.get_themes.set_active(False)
			elif self.current_state == "view_sources":
				self.changing_state = True
				self.view_sources.set_active(False)
			self.current_state = "get_types"
			self.changing_state = False
			self.filter_table.hide()
			try:
				self.vbox.destroy()
			except:
				pass
			
			#self.vbox is the main vbox for the left pane
			self.vbox = gtk.VBox(False)
			self.vbox.show()
			self.scrolled.add_with_viewport(self.vbox)
			
			#Get list of types from repositories
			self.view2_list = self.repositories.getTypes()
			self.view2_num_types = len(self.view2_list)
			self.view2_num_type_sources = 0
			
			#This part actually gets the number of sources with themes
			for self.view2_x in self.repositories.doc.documentElement.getElementsByTagName('source'):
				if self.repositories.getAttribute(self.view2_x,'type')=="type" or self.repositories.getAttribute(self.view2_x,'type')=="both":
					self.view2_num_type_sources = (self.view2_num_type_sources+1)
			
			#Create the treeview, liststore, etc for the list!
			
			#First, the liststore and treeview
			self.view2_liststore = gtk.ListStore(gtk.gdk.Pixbuf,str)
			self.view2_treeview = gtk.TreeView(self.view2_liststore)
			
			#pixbuf renderer and text renderer for first and second columns, respectively
			self.view2_pixbufrenderer = gtk.CellRendererPixbuf()
			self.view2_textrenderer = gtk.CellRendererText()

			#the columns for image and information, respectively
			self.view2_column0 = gtk.TreeViewColumn("Logo")
			self.view2_column1 = gtk.TreeViewColumn("Information")
			
			#Add the pixbuf renderer to column 0 (for screenshot/logo), and add the pixbuf option
			self.view2_column0.pack_start(self.view2_pixbufrenderer,True)
			self.view2_column0.add_attribute(self.view2_pixbufrenderer,'pixbuf',0)
			
			#Now add the text renderer to column 1 for information, and markup option (wow pango is awesome!)
			self.view2_column1.pack_start(self.view2_textrenderer,True)
			self.view2_column1.add_attribute(self.view2_textrenderer,'markup',1)
			
			#Now add the image column then the text column to the treeview
			self.view2_treeview.append_column(self.view2_column0)
			self.view2_treeview.append_column(self.view2_column1)
			
			#Now connect() the treeview for when a row is selected
			self.view2_get_selection = self.view2_treeview.get_selection()
			#You are not expected to understand this next line. It just changes the right pane on selecting a row
			self.view2_get_selection.connect("changed",lambda w: self.getTypesPane(self.view2_list[self.view2_liststore[w.get_selected()[1]].path[0]]))
			
			#Now show the treeview, and pack_start it to the left pane
			self.view2_treeview.show()
			self.vbox.pack_start(self.view2_treeview)
			
			#Go through each theme in the list
			for self.view2_x in self.view2_list:
				
				#Get the logo if there is one, and if not then get the utm logo. TODO: get stock dialog question mark
				if self.view2_x[self.repositories.TYPE_LOGO] is not None:
					if self.view2_x[self.repositories.TYPE_LOGO][0]!="/":
						self.view2_pixbuf = gtk.gdk.pixbuf_new_from_file(\
						self.repositories.getImagePath(self.view2_x[self.repositories.TYPE_LOGO]))
					else:
						self.view2_pixbuf = gtk.gdk.pixbuf_new_from_file(self.view2_x[self.repositories.TYPE_LOGO])
				else:
					self.view2_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
				
				#Scale the pixbuf if necessary
				if self.view2_pixbuf.get_width() > 48:
					self.view2_pixbuf = self.view2_pixbuf.scale_simple(48,self.view2_pixbuf.get_height(),gtk.gdk.INTERP_BILINEAR)
				if self.view2_pixbuf.get_height() > 48:
					self.view2_pixbuf = self.view2_pixbuf.scale_simple(self.view2_pixbuf.get_width(),48,gtk.gdk.INTERP_BILINEAR)
				
				#Create the string that has the title and credits. TODO: Add sort by and second information (# downloads, credits, type)
				self.view2_textview = "<big><b>%s</b></big>\n<i>%s</i>" % (\
				self.view2_x[self.repositories.TYPE_NAME], self.view2_x[self.repositories.TYPE_CREDITS])
				
				#Append the information to the liststore, which will be displayed by the treeview
				self.view2_liststore.append([self.view2_pixbuf, self.view2_textview])
			
			#Now create a label for the right pane, set line wrap to true (doesn't really work :/), show() it, and put it in the right pane
			self.view2_right_pane = gtk.Label("\n\n\n\nYou can download %s theme type%s from %s source%s.\n\nSelect a theme type from the list on the left\nto view more information about it here." % (self.view2_num_types, self.isNot1(self.view2_num_types), self.view2_num_type_sources, self.isNot1(self.view2_num_type_sources)))
			self.view2_right_pane.set_line_wrap(True)
			self.view2_right_pane.show()
			self.replaceRightPane(self.view2_right_pane)
	
	#This function is for right pane for theme type from repository
	def getTypesPane(self,typeinstance,showrepo=True):
		
		#Just like typeToGTK(), but this is not downloaded and from a repository
		#Create the main table
		self.gtp_table = gtk.Table(3,2)
		self.gtp_table.show()
		
		#Create the gtk.Image() for the logo, if it exists, if not, then stock question mark dialog question image icon...thing
		#Really create a gtk.gdk.pixbuf first, incase the logo needs to be resized. Much better than set_size_request
		#REALLY create a gtk.gdk.pixbuf if there is a logo...
		if typeinstance[self.repositories.TYPE_LOGO] is not None:
			
			#Find out if it's on the disk (I allow this for testing creating a repository)
			if typeinstance[self.repositories.TYPE_LOGO][0]=="/":
				self.gtp_pixbuf = gtk.gdk.pixbuf_new_from_file(typeinstance[self.repositories.TYPE_LOGO])
			else:
				self.gtp_pixbuf = gtk.gdk.pixbuf_new_from_file(self.repositories.getImagePath(typeinstance[self.repositories.TYPE_LOGO]))
			
			#Scale the pixbuf if necessary
			if self.gtp_pixbuf.get_width() > 48:
				self.gtp_pixbuf = self.gtp_pixbuf.scale_simple(48,self.gtp_pixbuf.get_height(),gtk.gdk.INTERP_BILINEAR)
			if self.gtp_pixbuf.get_height() > 48:
				self.gtp_pixbuf = self.gtp_pixbuf.scale_simple(self.gtp_pixbuf.get_width(),48,gtk.gdk.INTERP_BILINEAR)
			
			self.gtp_img = gtk.Image()
			self.gtp_img.set_from_pixbuf(self.gtp_pixbuf)
			self.gtp_img.show()
		else:
			self.gtp_img = gtk.Image()
			self.gtp_img.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
			self.gtp_img.show()
		
		#Attach the image to the table
		self.gtp_table.attach(self.gtp_img,0,1,0,2,xoptions=gtk.SHRINK)
		
		#Now for a full name label
		self.gtp_name_label = gtk.Label(typeinstance[self.repositories.TYPE_NAME])
		self.gtp_name_label.modify_font(pango.FontDescription('bold 14'))
		self.gtp_name_label.show()
		self.gtp_table.attach(self.gtp_name_label,1,2,0,1)
		
		#Now for a label that says what repository this theme type is from... if showrepo==True
		if showrepo==True:
			self.gtp_repo_label = gtk.Label("From the \"%s\" repository" % self.repositories.getRepoAttribute(typeinstance[self.repositories.TYPE_SOURCE_ID],'name'))
			self.gtp_repo_label.modify_font(pango.FontDescription('9'))
			self.gtp_repo_label.show()
			self.gtp_table.attach(self.gtp_repo_label,0,2,1,2)
		
		#Now for a description label and all that good stuff...
		if typeinstance[self.repositories.TYPE_DESCRIPTION] is not None:
			self.gtp_desc = gtk.Label(typeinstance[self.repositories.TYPE_DESCRIPTION])
			self.gtp_desc.set_line_wrap(True)
			self.gtp_desc.show()
			self.gtp_desc_window = gtk.ScrolledWindow()
			self.gtp_desc_window.set_border_width(0)
			self.gtp_desc_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
			self.gtp_desc_window.add_with_viewport(self.gtp_desc)
			self.gtp_desc_window.show()
			self.gtp_table.attach(self.gtp_desc_window,0,2,2,3)
		
		#Credits label. italicizied.
		self.gtp_credits = gtk.Label(typeinstance[self.repositories.TYPE_CREDITS])
		self.gtp_credits.modify_font(pango.FontDescription('italic'))
		self.gtp_credits.show()
		self.gtp_table.attach(self.gtp_credits,0,2,3,4,ypadding=7)
		
		#Now for a download button that will, of course, download and import the theme type
		self.gtp_download = gtk.Button(stock=gtk.STOCK_GO_DOWN)
		self.gtp_download.get_children()[0].get_children()[0].get_children()[1].set_text("Download")
		self.gtp_download.connect('clicked',lambda w: self.downloadType(typeinstance[self.repositories.TYPE_URL],typeinstance[self.repositories.TYPE_SOURCE_ID],typeinstance[self.repositories.TYPE_PACKAGE_LIKE_NAME]))
		self.gtp_download.show()
		self.gtp_table.attach(self.gtp_download,0,2,4,5,xoptions=gtk.SHRINK)
		
		#Now put the table in the right pane. I wish I wrote a function for the left pane like I did for the right. Oh well...
		self.replaceRightPane(self.gtp_table)
	
	#This function downloads the theme type and imports it. Stolen from downloadTheme().
	#Also updates the imported.xml file for source by sourceid
	def downloadType(self,url,sourceid,plname):
		
		#Download the theme file
		os.system('wget -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 --output-document=%s/.utm/sources/downloads/%s %s' % (self.homepath, url.split('/')[-1:][0], url))
		
		if True:
			#try to open the downloaded file, if failure then an exception will be raised and a dialog will be made
			self.dlt_fp = open('%s/.utm/sources/downloads/%s' % (self.homepath, url.split('/')[-1:][0]))
			self.dlt_fp.close()
			
			#import the theme
			self.importType('%s/.utm/sources/downloads/%s' % (self.homepath, url.split('/')[-1:][0]),False)
			
			#get the doc of the new type
			self.dlt_new_fp = open('%s/.utm/types/%s.xml' % (self.homepath, plname),'r')
			self.dlt_new_doc = FromXml(self.dlt_new_fp.read())
			self.dlt_new_fp.close()
			
			#open the imported list from the source, create an xml document from it, and close the file. this will add info about the recently
			#downloaded and imported theme type
			try:
				self.dlt_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, sourceid),'r')
				self.dlt_doc = FromXml(self.dlt_fp.read())
				self.dlt_fp.close()
			except:
				self.dlt_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, sourceid),'w+')
				self.dlt_fp.write("<?xml version='1.0' encoding='UTF-8'?>\n<source-imported/>")
				self.dlt_fp.close()
				self.dlt_doc = FromXml("<?xml version='1.0' encoding='UTF-8'?>\n<source-imported/>")
			
			#<item>\n<type>\ntype</type>\n<package-like-name>plname</package-like-name>\n<version>version</version>\n</item>
			self.dlt_element0 = self.dlt_doc.createElement('item')
			self.dlt_element1 = self.dlt_doc.createElement('type')
			self.dlt_element2 = self.dlt_doc.createElement('package-like-name')
			self.dlt_element3 = self.dlt_doc.createElement('version')
			
			self.dlt_textnode1 = self.dlt_doc.createTextNode('type')
			self.dlt_textnode2 = self.dlt_doc.createTextNode(self.repositories.getAttribute(\
				self.dlt_new_doc.documentElement.getElementsByTagName('info')[0],'package-like-name'))
			self.dlt_textnode3 = self.dlt_doc.createTextNode(str(self.repositories.getAttribute(\
				self.dlt_new_doc.documentElement.getElementsByTagName('info')[0],'version')))
			
			self.dlt_element1.appendChild(self.dlt_textnode1)
			self.dlt_element2.appendChild(self.dlt_textnode2)
			self.dlt_element3.appendChild(self.dlt_textnode3)
			
			self.dlt_element0.appendChild(self.dlt_element1)
			self.dlt_element0.appendChild(self.dlt_element2)
			self.dlt_element0.appendChild(self.dlt_element3)
			
			#Append self.dlt_element0 to the main doc, then prettyprint it.
			self.dlt_doc.documentElement.appendChild(self.dlt_element0)
			self.dlt_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, sourceid),'w')
			PrettyPrint(self.dlt_doc,self.dlt_fp)
			self.dlt_fp.close()
			
			#Now refresh, which will display get themes again, but this time the recently downloaded theme won't be there! (if it shouldn't be)
			self.refresh()
		
		else:
			#There was an error in downloading the file. So boring. Make dialog.
			self.simpleNetworkDialog('theme type')
	
	#This function makes the window close when it should. Also prints "Bye!"
	def destroy(self, widget=None, data=None):
		print "Bye!"
		gtk.main_quit()
	
	#Now for the function that converts a theme instance into a GTK Table
	def themeToGTK(self,theme):
		#This function owns self.ttg_*
		
		#Create the table that everything goes in. Will be returned
		self.ttg_table = gtk.Table(2,2,False)
		
		#If the provided theme has a path to a screenshot, then use it.
		if theme.getAttribute('screenshot') is not None:
			self.ttg_image = gtk.Image()
			self.ttg_image.set_from_file(theme.getAttribute('screenshot').replace("$HOME",self.homepath).replace("~",self.homepath))
			self.ttg_image.show()
		
		#Otherwise, use a stock question mark.
		else:
			self.ttg_image = gtk.Image()
			self.ttg_image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
			self.ttg_image.show()
		
		#Attach the screenshot/? to the table, at the top
		self.ttg_table.attach(self.ttg_image,0,2,0,1)
		
		#Now for the theme name/title
		self.ttg_title = gtk.Label(theme.getAttribute('title'))
		self.ttg_title.modify_font(pango.FontDescription('bold 16'))
		self.ttg_title.show()
		self.ttg_table.attach(self.ttg_title,0,2,1,2)
		
		#Now for a label that says what type this theme is and maybe what repo it's from
		for self.ttg_x in self.typeslist:
			if self.ttg_x.getAttribute('package-like-name')==theme.getAttribute('type'):
				if self.ttg_x.getAttribute('short-name') is not None:
					self.ttg_type_label = gtk.Label('%s Theme' % self.ttg_x.getAttribute('short-name'))
				else:
					self.ttg_type_label = gtk.Label('%s Theme' % self.ttg_x.getAttribute('full-name'))
		self.ttg_type_label.modify_font(pango.FontDescription('bold 10'))
		self.ttg_type_label.show()
		self.ttg_table.attach(self.ttg_type_label,0,2,2,3,xoptions=gtk.SHRINK)
		
		#Now for the credits label
		if theme.getAttribute('author') is not None:
			self.ttg_credits = gtk.Label('By %s' % theme.getAttribute('author'))
			self.ttg_credits.modify_font(pango.FontDescription('italic'))
			self.ttg_credits.show()
			self.ttg_table.attach(self.ttg_credits,0,2,3,4)
			
		#Now for the description label
		if theme.getAttribute('description') is not None:
			self.ttg_desc = gtk.Label(theme.getAttribute('description'))
			self.ttg_desc.set_line_wrap(True)
			self.ttg_desc.show()
			self.ttg_desc_window = gtk.ScrolledWindow()
			self.ttg_desc_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
			self.ttg_desc_window.add_with_viewport(self.ttg_desc)
			self.ttg_desc_window.show()
			self.ttg_table.attach(self.ttg_desc_window,0,2,5,6)
		
		#Now for an "Apply" button
		self.ttg_apply = gtk.Button(stock=gtk.STOCK_APPLY)
		self.ttg_apply.show()
		self.ttg_iterator = 0
		for self.ttg_x in self.typeplnames:
			if self.ttg_x==theme.getAttribute('type'):
				self.ttg_apply.iterator = self.ttg_iterator
				self.ttg_apply.connect("clicked",lambda w: self.subPopen(self.typeslist[w.iterator].getAttribute('apply').replace('%s','%s/.utm/theme-files/%s' % (self.homepath, theme.getAttribute('path'))).replace('$HOME',self.homepath).replace('~',self.homepath)))
				self.ttg_table.attach(self.ttg_apply,0,1,6,7,xoptions=gtk.SHRINK)
			self.ttg_iterator=self.ttg_iterator+1
		
		#Now for a "Remove" button
		self.ttg_remove = gtk.Button(stock=gtk.STOCK_REMOVE)
		self.ttg_remove.connect("clicked",lambda w:self.removeTheme(theme))
		self.ttg_remove.show()
		self.ttg_table.attach(self.ttg_remove,1,2,6,7,xoptions=gtk.SHRINK)
		
		#Now show and return the table
		self.ttg_table.show()
		self.replaceRightPane(self.ttg_table)
		
		#Now for a function to convert a type instance into a GTK Table. Should be simple and like themeToGTK
	def typeToGTK(self,typeinstance):
		#It has to be typeinstance because type is a keyword in python.
		#This function owns self.tyg_*. I chose "tyg" because I know it's type and not theme and it's easy to type. Is that a pun?
		
		#Create a table that everything will go in
		self.tyg_table = gtk.Table(2,2,False)
		
		#Try to make an image that is typeinstance's logo. On failure just use the stock question mark.
		if typeinstance.getAttribute('logo') is not None:
			self.tyg_image = gtk.Image()
			self.tyg_image.set_from_file(typeinstance.getAttribute('logo').replace("$HOME",self.homepath).replace("~",self.homepath))
			self.tyg_image.set_size_request(48,48)
			self.tyg_image.show()
		
		#No logo provided
		else:
			self.tyg_image = gtk.Image()
			self.tyg_image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
			self.tyg_image.show()
		
		#Create a label for the title, like in list mode
		self.tyg_title_label = gtk.Label(typeinstance.getAttribute('full-name'))
		self.tyg_title_label.set_line_wrap(True)
		self.tyg_title_label.modify_font(pango.FontDescription('bold 16'))
		self.tyg_title_label.show()
		
		#Create a label for the credits for the type (full credits)
		self.tyg_credits = gtk.Label(typeinstance.getAttribute('full-credits').replace("\\n","\n"))
		self.tyg_credits.set_line_wrap(True)
		self.tyg_credits.modify_font(pango.FontDescription('italic'))
		self.tyg_credits.show()
		
		#Label for the description.
		if typeinstance.getAttribute('description') is not None:
			self.tyg_desc_label = gtk.Label(typeinstance.getAttribute('description'))
			self.tyg_desc_label.set_line_wrap(True)
			self.tyg_desc_label.show()
			#self.tyg_desc_label.set_size_request(110,30)
			#Attach it now because otherwise they'll be an error in the attaching later
			self.tyg_table.attach(self.tyg_desc_label,0,2,2,3)
		
		#Find out how many themes this type has
		self.tyg_iterator = 0
		for self.tyg_x in self.typeplnames:
			if self.tyg_x==typeinstance.getAttribute('package-like-name'):
				self.tyg_num_themes = len(self.themesbytype[self.tyg_iterator])
			self.tyg_iterator = self.tyg_iterator+1
		
		#Now create a label that says that
		self.tyg_num_themes_label = gtk.Label('%s Theme%s' % (self.tyg_num_themes, self.isNot1(self.tyg_num_themes)))
		self.tyg_num_themes_label.modify_font(pango.FontDescription('bold'))
		self.tyg_num_themes_label.show()
		self.tyg_table.attach(self.tyg_num_themes_label,0,2,3,4)
		
		#Create a separator that will go under title/description/credits stuff. Simply here for looks. Kinda helps with the general structure
		self.tyg_separator = gtk.HSeparator()
		self.tyg_separator.show()
		
		
		#Now for a button that on clicking, will launch a browser opening the url wobsite == xkcd. Read about it in my blag. ;)
		if typeinstance.getAttribute('website') is not None:
			self.tyg_towobsite_label = gtk.Label("Open program website")
			self.tyg_towobsite_label.show()
			self.tyg_towobsite_button = gtk.Button(str(self.urlToHostName(typeinstance.getAttribute('website'))),gtk.STOCK_NETWORK)
			self.tyg_towobsite_button.get_children()[0].get_children()[0].get_children()[1].set_text(str(self.urlToHostName(typeinstance.getAttribute('website'))))
			self.tyg_towobsite_button.modify_font(pango.FontDescription('underline blue'))
			self.tyg_towobsite_button.connect("clicked",lambda w: self.openUrl(typeinstance.getAttribute('website')))
			self.tyg_towobsite_button.show()
			#Like description label, attach now
			self.tyg_table.attach(self.tyg_towobsite_label,0,1,6,7,xoptions=gtk.SHRINK)
			self.tyg_table.attach(self.tyg_towobsite_button,1,2,6,7,xoptions=gtk.SHRINK)
		
# 		#Now for a button that on clicking, will check for update to the theme type
# 		if typeinstance.getAttribute('update-url') is not None:
# 			self.tyg_update_label = gtk.Label("Check for updates")
# 			self.tyg_update_label.show()
# 			self.tyg_update_button = gtk.Button("Check Now",gtk.STOCK_APPLY)
# 			self.tyg_update_button.get_children()[0].get_children()[0].get_children()[1].set_text("Check Now")
# 			self.tyg_update_button.connect("clicked",self.checkForUpdates,typeinstance.getAttribute('update-url'),typeinstance)
# 			self.tyg_update_button.show()
# 			self.tyg_table.attach(self.tyg_update_label,0,1,7,8,xoptions=gtk.SHRINK)
# 			self.tyg_table.attach(self.tyg_update_button,1,2,7,8,xoptions=gtk.SHRINK)
		
		#Now for a button that on clicking, will delete the current theme type and all its themes
		self.tyg_delete_label = gtk.Label("Remove")
		self.tyg_delete_label.show()
		self.tyg_delete_button = gtk.Button(stock=gtk.STOCK_REMOVE)
		self.tyg_delete_button.connect("clicked",lambda w: self.removeType(typeinstance))
		self.tyg_delete_button.show()
		self.tyg_table.attach(self.tyg_delete_label,0,1,8,9,xoptions=gtk.SHRINK)
		self.tyg_table.attach(self.tyg_delete_button,1,2,8,9,xoptions=gtk.SHRINK)
		
			
		#Now for a button that on clicking, will export the current theme settings of the program
		if typeinstance.getAttribute('export') is not None:
			self.tyg_export_label = gtk.Label("Export Current Settings")
			self.tyg_export_label.show()
			self.tyg_export_button = gtk.Button("Export",gtk.STOCK_SAVE)
			self.tyg_export_button.get_children()[0].get_children()[0].get_children()[1].set_text("Export")
			self.tyg_export_button.connect("clicked",lambda w: subprocess.Popen(typeinstance.getAttribute('export').replace("$HOME",self.homepath).replace("~",self.homepath).split(' ')))
			self.tyg_export_button.show()
			self.tyg_table.attach(self.tyg_export_label,0,1,9,10,xoptions=gtk.SHRINK)
			self.tyg_table.attach(self.tyg_export_button,1,2,9,10,xoptions=gtk.SHRINK)
		
		#Now for a button that on clicking, will open a program to edit the current theme
		if typeinstance.getAttribute('edit-current') is not None:
			self.tyg_edit_current_label = gtk.Label("Edit Current Theme")
			self.tyg_edit_current_label.show()
			self.tyg_edit_current_button = gtk.Button(stock=gtk.STOCK_EDIT)
			self.tyg_edit_current_button.connect("clicked",lambda w: self.subPopen(typeinstance.getAttribute('edit-current')))
			self.tyg_edit_current_button.show()
			self.tyg_table.attach(self.tyg_edit_current_label,0,1,10,11,xoptions=gtk.SHRINK)
			self.tyg_table.attach(self.tyg_edit_current_button,1,2,10,11,xoptions=gtk.SHRINK)
		
		
		#Attach all the widgets to the table.
		#In order: Logo (Image), Title (Label), Credits (Label), Separator (Duh)
		self.tyg_table.attach(self.tyg_image,0,2,0,1,xoptions=gtk.SHRINK)
		self.tyg_table.attach(self.tyg_title_label,0,2,1,2,xoptions=gtk.SHRINK)
		self.tyg_table.attach(self.tyg_credits,0,2,4,5,xoptions=gtk.SHRINK)
		self.tyg_table.attach(self.tyg_separator,0,2,5,6)
		
		
		#Show and then replace the right pane with the table
		self.tyg_table.show()
		self.replaceRightPane(self.tyg_table)
	
	#A little easier to remember.
	def subPopen(self,command,stdout='/dev/null'):
		subprocess.Popen(command.split(' '),stdout=open(stdout,'w'))
	
	#Destroys the widget in the right ScrolledWindow, changes self.right_pane to argument newwidget, and adds it to the ScrolledWindow
	def replaceRightPane(self,newwidget):
		self.right_pane.destroy()
		self.right_pane = newwidget
		self.right_vbox.pack_start(self.right_pane,False,True)
	
	#Converts the url to the hostname
	def urlToHostName(self,url):
		url2 = url.split('/')
		return url2[2].split(':')[0]
	
# 	#Now a function that will check for updates+gui stuff...
# 	#I swear, I could not spell "response" for my life. I keep typing reponse... :/
# 	#---------DEPRECATED------------DO-NOT-USE---------DOESN'T-WORK--------------ET-CETERA
# 	def checkForUpdates(self,a,updateurl,typeinstance):
# 		#Create a dialog, do you want to connect to hostname to update program?, stock/reponse cancel, ok
# 		self.check_dialog = gtk.Dialog("Connect to %s?" % self.urlToHostName(updateurl),self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
# 		
# 		#Get the short name of the program e.g. "Awn" instead of "Avant Win...", or use full name if nonexistent
# 		if typeinstance.getAttribute('short-name') is not None:
# 			self.check_short_name = typeinstance.getAttribute('short-name')
# 		else:
# 			self.check_short_name = typeinstance.getAttribute('full-name')
# 		
# 		#Create the label ("do you want to..."), show it, pack it to the vbox.
# 		self.check_dialog_label = gtk.Label("Do you want to attempt to connect to \n%s to update %s?" % (self.urlToHostName(updateurl), self.check_short_name))
# 		self.check_dialog_label.show()
# 		self.check_dialog.vbox.pack_start(self.check_dialog_label,False,True,10)
# 		
# 		#Run the dialog box, and see what the response is.
# 		self.check_response = self.check_dialog.run()
# 		self.check_dialog.destroy()
# 		
# 		#User wants to connect to see if there is an update
# 		if gtk.RESPONSE_OK == self.check_response:
# 			
# 			#Call wget to download the information file (newest version\nnewest url)
# 			self.check_wget = subprocess.Popen(['wget','--tries=1','--timeout=5','--output-document='+self.homepath+'/.utm/check/%s.txt' % typeinstance.getAttribute('package-like-name'),updateurl],stdout=open('/dev/null','w'),stderr=open('/dev/null','w')).wait()
# 			
# 			#Open the file, get contents, and close the file. Then rm (remove) it.
# 			#If the file cannot open, then there was an error. Todo: make a dialog that says there was an error in downloading the file. 
# 			#Include a text view widget within a scrolledwindow() that has wget's stderr, (change from /dev/null to /tmp/something)
# 			self.check_itworked = False
# 			try:
# 				self.check_fp = open(self.homepath+'/.utm/check/%s.txt' % typeinstance.getAttribute('package-like-name'),'r')
# 				self.check_file_contents = self.check_fp.read()
# 				self.check_fp.close()
# 				subprocess.Popen(['rm',self.homepath+'/.utm/check/%s.txt' % typeinstance.getAttribute('package-like-name')]).wait()
# 				self.check_itworked = True
# 			except:
# 				self.check_dialogerr = gtk.Dialog('There was an error.',self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK,gtk.RESPONSE_OK))
# 				self.check_dialogerr_label = gtk.Label("There was an error in downloading the file.\nThe server may be down, but you may want to check your internet connection.\nPlease try again later.")
# 				self.check_dialogerr_label.show()
# 				self.check_dialogerr.vbox.pack_start(self.check_dialogerr_label,False,True,15)
# 				self.check_dialogerr.run()
# 				self.check_dialogerr.destroy()
# 			
# 			#Check if there was not an error. There's gotta be an easier way to do this.
# 			if self.check_itworked==True:
# 				
# 				#For exiting, etc.
# 				self.check_itworked = False
# 				
# 				#Parse the file, and get the newest version and the url to the file (self.check_newest_version/url)
# 				try:
# 					self.check_newest_version = self.check_file_contents.split('\n')[0]
# 					self.check_newest_url = self.check_file_contents.split('\n')[1]
# 					self.check_itworked = True
# 				except:
# 					self.check_dialogerr = gtk.Dialog('There was an error.',self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK,gtk.RESPONSE_OK))
# 					self.check_dialogerr_label = gtk.Label("There was an error in downloading the file.\nThe server may be down, but you may want to check your internet connection.\nPlease try again later.")
# 					self.check_dialogerr_label.show()
# 					self.check_dialogerr.vbox.pack_start(self.check_dialogerr_label,False,True,15)
# 					self.check_dialogerr.run()
# 					self.check_dialogerr.destroy()
# 				
# 				#If user does not have the latest version, say there's a new version and ask if you want to update it.
# 				if self.check_newest_version!=typeinstance.getAttribute('version') and self.check_itworked is True:
# 					
# 					#Create the dialog
# 					self.check_dialog2 = gtk.Dialog("New version of %s available!" % self.check_short_name,self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
# 					
# 					#Create the label ('a new version of...'), show it, pack it to the vbox
# 					self.check_dialog2_label = gtk.Label("A new version of %s is available. \nYou currently have version %s, and the newest is %s. \nUpgrade?" % (self.check_short_name, typeinstance.getAttribute('version'), self.check_newest_version))
# 					self.check_dialog2_label.show()
# 					self.check_dialog2.vbox.pack_start(self.check_dialog2_label,False,True,10)
# 					
# 					#Run the dialog and get the reponse
# 					self.check_response2 = self.check_dialog2.run()
# 					self.check_dialog2.destroy()
# 					
# 					#If user wants to update the type
# 					if self.check_response2==gtk.RESPONSE_OK:
# 						
# 						#wget the file, and import the type. (self.importType()). Then destroy the dialog.
# 						self.check_wget2 = subprocess.Popen(['wget','--output-document='+self.homepath+'/.utm/check/%s.tar.gz' % ".".join(self.check_newest_url.split('/')[-1].split('.')[:-2]),self.check_newest_url],stdout=open('/dev/null','w'),stderr=open('/dev/null','w')).wait()
# 						self.importType(self.homepath+'/.utm/check/%s.tar.gz' % ".".join(self.check_newest_url.split('/')[-1].split('.')[:-2]),False)
# 				
# 				#No new version is available :(
# 				else:
# 					if self.check_itworked==True:
# 						#Create a dialog, title no new version of program is available. button: ok don't get response.
# 						#label you currently have the latest version. show() it. packit to vbox, run the dialog, destroy the dialog. done.
# 						self.check_dialog2 = gtk.Dialog("No new version of %s is available." % self.check_short_name,self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK, gtk.RESPONSE_OK))
# 						self.check_dialog2_label = gtk.Label("You currently have the latest version of %s. (%s)" % (self.check_short_name, self.check_newest_version))
# 						self.check_dialog2_label.show()
# 						self.check_dialog2.vbox.pack_start(self.check_dialog2_label,False,True,10)
# 						self.check_dialog2.run()
# 						self.check_dialog2.destroy()
				
		
	#This function is to be connect()ed from a button for remove. Obviously removes a theme. Now deals with repositories.
	def removeTheme(self,theme):
		#This function owns self.tr_*
		#This is a Dialog Box, label "Are you sure you want to remove this theme?", HSeperator, ButtonBox, bottom left = Destroy, right = Cancel
		#If user says its ok then delete the theme.
		
		#Create the window. self.tr_win Title: "Are you sure?"
		self.tr_win = gtk.Dialog("Are you sure?",self.w,gtk.DIALOG_DESTROY_WITH_PARENT)
		self.tr_win.connect("delete_event",lambda a, b: self.tr_win.destroy())
		#Set the buttonbox to gtk.BUTTONBOX_EDGE, so bottom left and bottom right, not both bottom right. My preference, I guess.
		self.tr_win.get_children()[0].get_children()[1].set_layout(gtk.BUTTONBOX_EDGE)
		
		#Create the label "Are you sure..." Show() it, then pack it into the dialog box's vbox with a little padding
		self.tr_label = gtk.Label("Are you sure you want to remove this theme?")
		self.tr_label.show()
		self.tr_win.vbox.pack_start(self.tr_label,False,True,10)
		
		#Create a Yes button, stock delete icon, text "Remove", onclicking will destroy the dialog box and actually delete the theme
		#Then add it to the dialog's buttonbox
		self.tr_yes = gtk.Button(stock=gtk.STOCK_REMOVE)
		self.tr_yes.show()
		#self.tr_yes.get_children()[0].get_children()[0].get_children()[1].set_text('Remove')
		self.tr_yes.connect("clicked",lambda w: self.removeTheme2(theme))
		self.tr_yes.connect("clicked",lambda w: self.tr_win.destroy())
		self.tr_win.get_children()[0].get_children()[2].add(self.tr_yes)
		
		#Now create a no button that with stock close+'Cancel' text, simply destroys the dialog. Then add it to the buttonbox+make it default
		self.tr_no = gtk.Button(stock=gtk.STOCK_CLOSE)
		self.tr_no.show()
		self.tr_no.get_children()[0].get_children()[0].get_children()[1].set_text('Cancel')
		self.tr_no.connect("clicked",lambda w: self.tr_win.destroy())
		self.tr_win.get_children()[0].get_children()[2].add(self.tr_no)
		self.tr_no.set_flags(gtk.CAN_DEFAULT)
		self.tr_no.grab_default()
		
		#Run the dialog box window.
		self.tr_win.run()
		self.tr_win.destroy()
		
	
	#This function actually deletes the theme.
	def removeTheme2(self,theme):
		
		#Open() the themes xml file for reading, to get the xml doc, then close()
		self.tr2_fp = open('%s/.utm/themes.xml' % self.homepath,'r')
		self.tr2_doc = FromXml(self.tr2_fp.read())
		self.tr2_fp.close()
		
		#Now go through the elements, and if the filename of the theme xml file is the same as the provided theme's path
		#If it is, then delete that element
		for self.tr2_x in self.tr2_doc.documentElement.getElementsByTagName("theme"):
			if self.tr2_x.getElementsByTagName("filename")[0].childNodes[0].data==theme.getAttribute('xml-file'):
				self.tr2_doc.documentElement.removeChild(self.tr2_x)
		
		#Now open() the themes xml file for writing so the (hopefully) recently changed xml document can be written to the hard drive.
		#And write it.
		self.tr2_fp = open('%s/.utm/themes.xml' % self.homepath,'w')
		PrettyPrint(self.tr2_doc,self.tr2_fp)
		self.tr2_fp.close()
		
		#Parse the filename of the theme to get the xml file, for deleting
		self.tr2_filename = theme.getAttribute('xml-file')
		if (self.tr2_filename.split('.')[-2]=="tar" and self.tr2_filename.split('.')[-1]=="gz") \
		or (self.tr2_filename.split('.')[-2]=="tar" and self.tr2_filename.split('.')[-1]=="bz2"):
			self.tr2_new_filename = ".".join(self.tr2_filename.split('.')[:-2])+".xml"
		else:
			self.tr2_new_filename = ".".join(self.tr2_filename.split('.')[:-1])+".xml"
		
		print self.tr2_new_filename
		
		#Now remove the actual theme files (actual package, info file (says the name, author, etc.))
		os.system('rm %s/.utm/theme-files/%s' % (self.homepath, theme.getAttribute('xml-file')))
		os.system('rm %s/.utm/themes/%s' % (self.homepath, self.tr2_new_filename))
		
		#Go through the repositories, if one claims it downloaded this theme, delete that record
		#Also removes dupe claims, how convenient.
		for self.tr_x in self.repositories.doc.documentElement.getElementsByTagName('source'):
			#Open iterated repository imported file
			self.tr_fp2 = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, self.repositories.getAttribute(self.tr_x,'id')),'r')
			self.tr_doc2 = FromXml(self.tr_fp2.read())
			self.tr_fp2.close()
			for self.tr_y in self.tr_doc2.documentElement.getElementsByTagName('item'):
				if self.repositories.getAttribute(self.tr_y,'type')=="theme":
					if self.repositories.getAttribute(self.tr_y,'theme-type')==theme.getAttribute('type'):
						if self.repositories.getAttribute(self.tr_y,'filename')==self.tr2_new_filename:
							self.tr_doc2.documentElement.removeChild(self.tr_y)
			
			self.tr_fp2 = open('%s/.utm/sources/%s/imported.xml' % (self.homepath, self.repositories.getAttribute(self.tr_x,'id')),'w')
			PrettyPrint(self.tr_doc2,self.tr_fp2)
			self.tr_fp2.close()
		
		
		#Now refresh the list with refresh()
		self.refresh()
	
	#Removes a type and all of its themes
	def removeType(self,typeinstance):
		#This function owns self.dt_*
		#This is a Dialog Box, label "Are you sure you want to remove this theme type?", HSeperator, bbox, bottom left = Destroy, right = Cancel
		
		#Create the window. self.dt_win Title: "Are you sure?"
		self.dt_win = gtk.Dialog("Are you sure?",self.w,gtk.DIALOG_DESTROY_WITH_PARENT)
		self.dt_win.connect("delete_event",lambda a, b: self.dt_win.destroy())
		#Set the buttonbox to gtk.BUTTONBOX_EDGE, so bottom left and bottom right, not both bottom right. My preference, I guess.
		self.dt_win.get_children()[0].get_children()[1].set_layout(gtk.BUTTONBOX_EDGE)
		
		#Create the label "Are you sure..." Show() it, then pack it into the dialog box's vbox with a little padding
		self.dt_label = gtk.Label("Are you sure you want to remove this theme type and all of its themes?")
		self.dt_label.show()
		self.dt_win.vbox.pack_start(self.dt_label,False,True,10)
		
		#Create a Yes button, stock delete icon, text "Remove", onclicking will destroy the dialog box and actually delete the theme type
		#Then add it to the dialog's buttonbox
		self.dt_yes = gtk.Button(stock=gtk.STOCK_DELETE)
		self.dt_yes.show()
		self.dt_yes.get_children()[0].get_children()[0].get_children()[1].set_text('Remove')
		self.dt_yes.connect("clicked",lambda w: self.removeType2(typeinstance))
		self.dt_yes.connect("clicked",lambda w: self.dt_win.destroy())
		self.dt_win.get_children()[0].get_children()[2].add(self.dt_yes)
		
		#Now create a no button that with stock close+'Cancel' text, simply destroys the dialog. Then add it to the buttonbox
		self.dt_no = gtk.Button(stock=gtk.STOCK_CLOSE)
		self.dt_no.show()
		self.dt_no.get_children()[0].get_children()[0].get_children()[1].set_text('Cancel')
		self.dt_no.connect("clicked",lambda w: self.dt_win.destroy())
		self.dt_win.get_children()[0].get_children()[2].add(self.dt_no)
		self.dt_no.set_flags(gtk.CAN_DEFAULT)
		self.dt_no.grab_default()
		
		#Run the dialog box window.
		self.dt_win.run()
	
	#This function actually deletes the theme type and ALL of its themes.
	def removeType2(self,typeinstance):
		
		#Open the themes xml file for reading to get an xml document
		self.dt2_fp = open('%s/.utm/themes.xml' % self.homepath,'r')
		self.dt2_doc = FromXml(self.dt2_fp.read())
		self.dt2_fp.close()
		
		#Now, go through each theme, open its theme file, find out its theme type. If it is the same as the typeinstance's plname, then
		#Remove that file from the hard drive and that element from the themes xml document
		for self.dt2_x in self.dt2_doc.documentElement.getElementsByTagName("theme"):
			
			self.dt2_fp2 = open('%s/.utm/themes/%s' % (self.homepath, self.dt2_x.getElementsByTagName("filename")[0].childNodes[0].data),'r')
			self.dt2_doc2 = FromXml(self.dt2_fp2.read())
			self.dt2_fp2.close()
			
			if self.dt2_doc2.documentElement.getElementsByTagName("type")[0].childNodes[0].data==typeinstance.getAttribute('package-like-name'):
				os.system('rm %s/.utm/themes/%s' % (self.homepath, self.dt2_x.getElementsByTagName("filename")[0].childNodes[0].data))
				self.dt2_doc.documentElement.removeChild(self.dt2_x)
		
		#Now open the themes xml file for writing, write the new xml document to it, then close
		self.dt2_fp = open('%s/.utm/themes.xml' % self.homepath, 'w')
		PrettyPrint(self.dt2_doc,self.dt2_fp)
		self.dt2_fp.close()
		
		#Now, we open the types xml file for reading to get the xml doc and close
		self.dt2_fp = open('%s/.utm/types.xml' % self.homepath, 'r')
		self.dt2_doc = FromXml(self.dt2_fp.read())
		self.dt2_fp.close()
		
		#Now go through each element, if its package-like-name==the typeinstance's pacakge-like-name, then remove it.
		for self.dt2_y in self.dt2_doc.documentElement.getElementsByTagName("theme-type"):
			if self.dt2_y.getElementsByTagName('package-like-name')[0].childNodes[0].data==typeinstance.getAttribute('package-like-name'):
				self.dt2_doc.documentElement.removeChild(self.dt2_y)
		
		#Now open the types xml file so the new document can be written
		self.dt2_fp = open('%s/.utm/types.xml' % self.homepath, 'w')
		PrettyPrint(self.dt2_doc,self.dt2_fp)
		self.dt2_fp.close()
		
		#Now call the typeinstance's uninstall command, if it is not None (exists)
		if typeinstance.getAttribute('uninstall') is not None:
			os.system(typeinstance.getAttribute('uninstall'))
		
		#Now delete all the dirs that the type owns. ~/.utm/theme-files/plname, themes/plname, type-files/plname, and types/plname.xml
		os.system('rm -r ~/.utm/theme-files/%s' % typeinstance.getAttribute('package-like-name'))
		os.system('rm -r ~/.utm/themes/%s' % typeinstance.getAttribute('package-like-name'))
		os.system('rm -r ~/.utm/type-files/%s' % typeinstance.getAttribute('package-like-name'))
		os.system('rm -r ~/.utm/types/%s.xml' % typeinstance.getAttribute('package-like-name'))
		
		#And refresh.
		self.refresh()
	
	#This function is a little wrapper to call either self.themeToGTK or self.typeToGTK, depending on what the item is
	def tatWrapper(self,instance):
		try:
			instance.getShortName
			self.typeToGTK(instance)
		except:
			self.themeToGTK(instance)
	
	#This function used to be in __init__, but now it's its own function because the refresh button needs to connect() to something
	def viewTypesAndThemes(self,ignore=None):
		self.current_state = "list"
		try:
			self.filter_table.show()
			self.refresh_button.set_sensitive(True)
		except:
			pass
		try:
			self.vbox.destroy()
		except:
			pass
		#self.vbox is the main vbox for the left pane
		self.vbox = gtk.VBox(False,10)
		self.vbox.show()
		self.scrolled.add_with_viewport(self.vbox)
		
		#Now we're going to go through each type and theme and sort of create an index. 
		#This will be used later on, particually by type and themeToGTK.
		self.iterator = 0
		self.typeslist = self.xml.getTypesList()
		self.themeslist = self.xml.getThemesList()
		self.typeplnames = []
		self.themesbytype = []
		self.items = []
		
		#Sort the types by name
		self.typeslist.sort(lambda x, y: cmp(x.getShortName(), y.getShortName()))
		
		#Now for the actual "indexing"
		#Go through each type and add data
		for self.types in self.typeslist:
			self.typeplnames.append(self.types.getAttribute('package-like-name'))
			self.themesbytype.append([])
			
			#Go through each theme of this type and add data
			for self.themes in self.themeslist:
				if self.themes.getAttribute('type')==self.types.getAttribute('package-like-name'):
					self.themesbytype[self.iterator].append(self.themes)
			
			#Iterate the iterator, used for matching a theme to a type
			self.iterator = self.iterator+1
		
		#Now sort the themes by name/title
		for self.x in self.themesbytype:
			#self.items.append(self.x)
			self.x.sort(lambda x,y: cmp(x.getAttribute('title'),y.getAttribute('title')))
		
		#self.items is a list of items, type, themes of type, type, themes of type, etc.
		self.iterator = 0
		for self.x in self.typeslist:
			self.items.append(self.x)
			for self.y in self.themesbytype[self.iterator]:
				self.items.append(self.y)
			self.iterator = (self.iterator+1)
		
		#Now make typeplnames a global variable so the repository class can use it
		self.repositories.setTypePlnames(self.typeplnames)
		
		#Now create the treeview and all that good stuff (stolen from get themes, oh my!)
		
		#First, the liststore and treeview
		self.viewT_liststore = gtk.ListStore(gtk.gdk.Pixbuf,str)
		self.viewT_treeview = gtk.TreeView(self.viewT_liststore)
		
		#pixbuf renderer and text renderer for first and second columns, respectively
		self.viewT_pixbufrenderer = gtk.CellRendererPixbuf()
		self.viewT_textrenderer = gtk.CellRendererText()

		#the columns for image and information, respectively
		self.viewT_column0 = gtk.TreeViewColumn("Image")
		self.viewT_column1 = gtk.TreeViewColumn("Information")
		
		#Add the pixbuf renderer to column 0 (for screenshot/logo), and add the pixbuf option
		self.viewT_column0.pack_start(self.viewT_pixbufrenderer,True)
		self.viewT_column0.add_attribute(self.viewT_pixbufrenderer,'pixbuf',0)
		
		#Now add the text renderer to column 1 for information, and markup option (wow pango is awesome!)
		self.viewT_column1.pack_start(self.viewT_textrenderer,True)
		self.viewT_column1.add_attribute(self.viewT_textrenderer,'markup',1)
		
		#Now add the image column then the text column to the treeview
		self.viewT_treeview.append_column(self.viewT_column0)
		self.viewT_treeview.append_column(self.viewT_column1)
		
		#Now connect() the treeview for when a row is selected
		self.viewT_get_selection = self.viewT_treeview.get_selection()
		#You are not expected to understand this next line. It just changes the right pane on selecting a row
		self.viewT_get_selection.connect("changed",lambda w,x: self.tatWrapper(self.items[self.viewT_liststore[w.get_selected()[1]].path[0]]),False)
		
		#Now show the treeview, and pack_start it to the left pane
		self.viewT_treeview.show()
		self.vbox.pack_start(self.viewT_treeview)
		
		#Now go through each theme and type in order, and add the pixbuf and info to the list store
		#TODO: clean this up
		self.iterator = 0
		for self.x in self.themesbytype:
			self.viewT_path_to_icon = self.typeslist[self.iterator].getAttribute('logo')
			if self.viewT_path_to_icon is not None:
				try:
					self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_icon.replace("$HOME",self.homepath).replace("~",self.homepath))
				except:
					self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
			else:
				self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
			#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
			self.viewT_w = self.viewT_pixbuf.get_width()
			self.viewT_h = self.viewT_pixbuf.get_height()
			if self.viewT_w==self.viewT_h:
				self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
			else:
				self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
			self.viewT_info = "<big><b>%s</b></big>\nTheme Type" % self.typeslist[self.iterator].getAttribute('full-name')
			self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
			for self.y in self.x:
				self.viewT_path_to_screenshot = self.y.getAttribute('screenshot')
				if self.viewT_path_to_screenshot is not None:
					try:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_screenshot.replace("$HOME",self.homepath).replace("~",self.homepath))
					except:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
				else:
					self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
				#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
				self.viewT_w = self.viewT_pixbuf.get_width()
				self.viewT_h = self.viewT_pixbuf.get_height()
				if self.viewT_w==self.viewT_h:
					self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
				else:
					self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
				self.viewT_info = "<big><b>%s</b></big>\n%s theme" % (self.y.getAttribute('title'), self.typeslist[self.typeplnames.index(self.y.getAttribute('type'))].getShortName())
				self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
			self.iterator = (self.iterator+1)
		
		self.new_right_pane = gtk.Label("\n\nSelect a theme or type on the left\nto view information about it here.\n\nYou have %s theme type%s and %s theme%s." % (len(self.typeslist), self.isNot1(len(self.typeslist)), len(self.themeslist), self.isNot1(len(self.themeslist))))
		self.new_right_pane.show()
		self.replaceRightPane(self.new_right_pane)
		
		try:
			if self.filter_entry.get_text()!="" and self.filter_entry.get_text()!="Filter...":
				self.filterList(self.filter_entry.get_text())
		except:
			pass
	
	#Filters the main list (imported types and themes) by filterstring (title/name(s), credits, description)
	def filterList(self,filterstring=None):
		if filterstring is None:
			filterstring=""
		
		#Not really sure how much of this next part is necessary...
		self.current_state = "list"
		try:
			self.filter_table.show()
			self.refresh_button.set_sensitive(True)
		except:
			pass
		try:
			self.vbox.destroy()
		except:
			pass
		
		#self.vbox is the main vbox for the left pane
		self.vbox = gtk.VBox(False,10)
		self.vbox.show()
		self.scrolled.add_with_viewport(self.vbox)
		
		#Now we're going to go through each type and theme and sort of create an index. 
		#This will be used later on, particually by type and themeToGTK.
		self.iterator = 0
		#self.typeslist = self.xml.getTypesList()
		#self.themeslist = self.xml.getThemesList()
		self.typeplnames = []
		self.themesbytype = []
		self.items = []
		
		#Sort the types by (shorter) name
		self.typeslist.sort(lambda x, y: cmp(x.getShortName(), y.getShortName()))
		
		#Now for the actual "indexing"
		for self.types in self.typeslist:
			self.items.append(self.types)
			self.typeplnames.append(self.types.getAttribute('package-like-name'))
			self.themesbytype.append([])
			for self.themes in self.themeslist:
				if self.themes.getAttribute('type')==self.types.getAttribute('package-like-name'):
					self.items.append(self.themes)
					self.themesbytype[self.iterator].append(self.themes)
			self.iterator = self.iterator+1
		
		#Now sort the themes by name/title
		for self.x in self.themesbytype:
			self.x.sort(lambda x,y: cmp(x.getAttribute('title'),y.getAttribute('title')))
		
		#Now create the treeview and all that good stuff (stolen from get themes, oh my!)
		
		#First, the liststore and treeview
		self.viewT_liststore = gtk.ListStore(gtk.gdk.Pixbuf,str)
		self.viewT_treeview = gtk.TreeView(self.viewT_liststore)
		
		#pixbuf renderer and text renderer for first and second columns, respectively
		self.viewT_pixbufrenderer = gtk.CellRendererPixbuf()
		self.viewT_textrenderer = gtk.CellRendererText()

		#the columns for image and information, respectively
		self.viewT_column0 = gtk.TreeViewColumn("Image")
		self.viewT_column1 = gtk.TreeViewColumn("Information")
		
		#Add the pixbuf renderer to column 0 (for screenshot/logo), and add the pixbuf option
		self.viewT_column0.pack_start(self.viewT_pixbufrenderer,True)
		self.viewT_column0.add_attribute(self.viewT_pixbufrenderer,'pixbuf',0)
		
		#Now add the text renderer to column 1 for information, and markup option (wow pango is awesome!)
		self.viewT_column1.pack_start(self.viewT_textrenderer,True)
		self.viewT_column1.add_attribute(self.viewT_textrenderer,'markup',1)
		
		#Now add the image column then the text column to the treeview
		self.viewT_treeview.append_column(self.viewT_column0)
		self.viewT_treeview.append_column(self.viewT_column1)
		
		#Now connect() the treeview for when a row is selected
		self.viewT_get_selection = self.viewT_treeview.get_selection()
		#You are not expected to understand this next line. It just changes the right pane on selecting a row
		self.viewT_get_selection.connect("changed",lambda w,x: self.tatWrapper(self.items[self.viewT_liststore[w.get_selected()[1]].path[0]]),False)
		
		#Now go through each theme and type in order, and add the pixbuf and info to the list store
		#You are not expected to understand this.
		#Try if you want to, though...
		self.iterator = 0
		self.count = 0
		for self.x in self.themesbytype:
			
			#If filtering
			if filterstring!="":
				
				#If type matches criteria
				if len(self.typeslist[self.iterator].getAttribute('full-name').lower().replace('\\n',' ').split(filterstring))!=1 or \
				len(self.typeslist[self.iterator].getAttribute('short-name').lower().replace('\\n',' ').split(filterstring))!=1 or \
				len(self.typeslist[self.iterator].getAttribute('description').lower().replace('\\n',' ').split(filterstring))!=1 or \
				len(self.typeslist[self.iterator].getAttribute('short-credits').lower().replace('\\n',' ').split(filterstring))!=1 or \
				len(self.typeslist[self.iterator].getAttribute('full-credits').lower().replace('\\n',' ').split(filterstring))!=1:
					#Increate the iterator
					self.count = self.count+1
					
					#Get the pixbuf of the type's icon/logo OR UTM logo
					self.viewT_path_to_icon = self.typeslist[self.iterator].getAttribute('logo')
					if self.viewT_path_to_icon is not None:
						try:
							self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_icon.replace("$HOME",self.homepath).\
							replace("~",self.homepath))
						except:
							self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
					else:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
					#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
					self.viewT_w = self.viewT_pixbuf.get_width()
					self.viewT_h = self.viewT_pixbuf.get_height()
					if self.viewT_w==self.viewT_h:
						self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
					else:
						self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
					#Create an information string, formatted for pango
					self.viewT_info = "<big><b>%s</b></big>\nTheme Type" % self.typeslist[self.iterator].getAttribute('full-name')
					
					#Append the data to the list store so it'll be displayed
					self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
			else:
				self.count = self.count+1
				self.viewT_path_to_icon = self.typeslist[self.iterator].getAttribute('logo')
				if self.viewT_path_to_icon is not None:
					try:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_icon.replace("$HOME",self.homepath).replace("~",self.homepath))
					except:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
				else:
					self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
				#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
				self.viewT_w = self.viewT_pixbuf.get_width()
				self.viewT_h = self.viewT_pixbuf.get_height()
				if self.viewT_w==self.viewT_h:
					self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
				else:
					self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
				self.viewT_info = "<big><b>%s</b></big>\nTheme Type" % self.typeslist[self.iterator].getAttribute('full-name')
				self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
			
			for self.y in self.x:
				if filterstring!="":
					if len(self.y.getAttribute('title').lower().replace('\\n',' ').split(filterstring))!=1 or len(self.y.getAttribute('description').lower().replace('\\n',' ').split(filterstring))!=1 or len(self.y.getAttribute('author').lower().replace('\\n',' ').split(filterstring))!=1:
						self.count = self.count+1
						self.viewT_path_to_screenshot = self.y.getAttribute('screenshot')
						if self.viewT_path_to_screenshot is not None:
							try:
								self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_screenshot.replace("$HOME",self.homepath).replace("~",self.homepath))
							except:
								self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
						else:
							self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
						#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
						self.viewT_w = self.viewT_pixbuf.get_width()
						self.viewT_h = self.viewT_pixbuf.get_height()
						if self.viewT_w==self.viewT_h:
							self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
						else:
							self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
						self.viewT_info = "<big><b>%s</b></big>\n%s theme" % (self.y.getAttribute('title'), self.typeslist[self.typeplnames.index(self.y.getAttribute('type'))].getShortName())
						self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
				else:
					self.count = self.count+1
					self.viewT_path_to_screenshot = self.y.getAttribute('screenshot')
					if self.viewT_path_to_screenshot is not None:
						try:
							self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file(self.viewT_path_to_screenshot.replace("$HOME",self.homepath).replace("~",self.homepath))
						except:
							self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
					else:
						self.viewT_pixbuf = gtk.gdk.pixbuf_new_from_file('%s/.utm/logo.png' % self.homepath)
					#Scale the pixbuf if necessary. Do some smarter things to at least kinda keep the aspect ratio
					self.viewT_w = self.viewT_pixbuf.get_width()
					self.viewT_h = self.viewT_pixbuf.get_height()
					if self.viewT_w==self.viewT_h:
						self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,48,gtk.gdk.INTERP_BILINEAR)
					else:
						self.viewT_pixbuf = self.viewT_pixbuf.scale_simple(48,int(self.viewT_h*(float(self.viewT_h)/float(self.viewT_w))),gtk.gdk.INTERP_BILINEAR)
					self.viewT_info = "<big><b>%s</b></big>\n%s theme" % (self.y.getAttribute('title'), self.typeslist[self.typeplnames.index(self.y.getAttribute('type'))].getShortName())
					self.viewT_liststore.append([self.viewT_pixbuf,self.viewT_info])
			self.iterator = (self.iterator+1)
		
		self.new_right_pane = gtk.Label("\n\nSelect a theme or type on the left\nto view information about it here.\n\nYou have %s theme type%s and %s theme%s." % (len(self.typeslist), self.isNot1(len(self.typeslist)), len(self.themeslist), self.isNot1(len(self.themeslist))))
		self.new_right_pane.show()
		self.replaceRightPane(self.new_right_pane)
		
		#In case no themes or theme types were found...
		if self.count==0:
			self.filter_none_label = gtk.Label("\nNo themes or theme types\nmatched your criteria.")
			self.filter_none_label.modify_font(pango.FontDescription('14'))
			self.filter_none_label.show()
			self.vbox.pack_start(self.filter_none_label)
		
		#Otherwise, show everything as usual
		else:
			#Show the treeview, and pack_start it to the left pane (if themes/types were found)
			self.viewT_treeview.show()
			self.vbox.pack_start(self.viewT_treeview)
	
	#Create an about window
	#This code was copied for Neil J. Patel's Awn Manager program and edited for UTM
	def about(self, ignore):
		self.about_win = gtk.AboutDialog()
		self.about_win.set_name("Ultimate Theme Manager")
		self.about_win.set_copyright("Copyright 2007 sharkbaitbobby <sharkbaitbobby+utm@gmail.com>")
		self.about_win.set_authors(["sharkbaitbobby <sharkbaitbobby+utm@gmail.com>"])
		self.about_win.set_comments("A universal theme manager for any program on the linux platform.")
		self.about_win.set_license("This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.")
		self.about_win.set_wrap_license(True)
		self.about_win.set_website("http://ultimate-theme-manager.googlecode.com")
		self.about_win.set_documenters(["sharkbaitbobby <sharkbaitbobby+utm@gmail.com>"])
		self.about_win.set_artists(["GTK Stock Icons","sharkbaitbobby with Kolourpaint"])
		self.about_win.run()
		self.about_win.destroy()
	
	#Create a window for simple help
	def help(self, ignore):
		self.help_win = gtk.Dialog("UTM Help",self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT))
		self.help_win.set_size_request(500,400)
		
		#Create the table that (almost) everything will go into
		self.help_table = gtk.Table(5,2)
		
		#Create the question mark icon
		self.help_image = gtk.Image()
		self.help_image.set_from_file('%s/.utm/logo24.png' % self.homepath)
		#self.help_image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
		self.help_image.show()
		
		#Ultimate Theme Manager Help label
		self.help_label = gtk.Label("Ultimate Theme Manager Help")
		self.help_label.modify_font(pango.FontDescription('bold 17'))
		self.help_label.show()
		
		#Now create a text view thing for all the text in a scrolledwindow
		self.help_text_view = gtk.TextView()
		self.help_text_view.set_editable(False)
		self.help_text_buffer = self.help_text_view.get_buffer()
		self.help_text_iter = self.help_text_buffer.get_iter_at_offset(0)
		self.help_text_buffer.insert(self.help_text_iter, "   Click the \"Open\" button to select a new theme or theme type. \nA popup will be shown, and you'll have to click which button corresponds \nwith what you selected from the list. For example: You pick a new theme \ntype, and the popup shows. You click \"Theme Type\", and that type is \nadded to the list. If it was a theme file, you would click on what type \nof theme that was, such as a GTK, Firefox, or Awn Theme, and that theme \nwill be added to the correct place.\n   To update a theme type to a newer version, select that theme type \nfrom the list and click \"Check Now\". If an update is available, follow the \ninstructions to update your theme type. A working internet connection \nis required for this. An update would occur if the website of the \nprogram of the theme type moved, or if there is a new format to that \ntype's themes.",-1)
		self.help_text_view.show()
		self.help_scrolled = gtk.ScrolledWindow()
		self.help_scrolled.add_with_viewport(self.help_text_view)
		self.help_scrolled.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.help_scrolled.show()
		
		#For more help go to label
		self.help_more_help = gtk.Label("For more help go to")
		self.help_more_help.show()
		
		#http://ultimate-theme-manager.googlecode.com go to button
		self.help_more_help_button = gtk.Button('http://ultimate-theme-manager.googlecode.com')
		self.help_more_help_button.connect('clicked',lambda w: self.openUrl('http://code.google.com/p/ultimate-theme-manager'))
		self.help_more_help_button.show()
		
		#Now attach() everything to the table and show() it
		self.help_table.attach(self.help_image,0,1,0,1,yoptions=gtk.SHRINK,ypadding=5)
		self.help_table.attach(self.help_label,1,2,0,1,yoptions=gtk.SHRINK,ypadding=5)
		self.help_table.attach(self.help_scrolled,0,2,1,2)		self.help_table.attach(self.help_more_help,0,2,3,4,yoptions=gtk.SHRINK)
		self.help_table.attach(self.help_more_help_button,0,2,4,5,gtk.SHRINK,gtk.SHRINK,ypadding=10)
		self.help_table.show()
		
		#And finish everything for the dialog
		self.help_win.vbox.pack_start(self.help_table)
		self.help_win.run()
		self.help_win.destroy()
	
	def isNot1(self,isit):
		if isit!=1:
			return "s"
		else:
			return ""
	
	#This function will open the provided url in the user's default browser (and terminal, if needed). GNOME only for now :(
	def openUrl(self,url):
		#If a gconf client doesn't exist yet, create it.
		try:
			self.client
		except:
			self.client = gconf.client_get_default()
		
		#Get the default browser and if it needs a terminal
		self.openUrl_default_browser = self.client.get_value('/desktop/gnome/applications/browser/exec')
		self.openUrl_browser_terminal = self.client.get_value('/desktop/gnome/applications/browser/needs_term')
		
		#It needs a terminal.
		if self.openUrl_browser_terminal==True:
			
			#Get the terminal and the execute argument so the browser will open in it.
			self.openUrl_default_terminal = self.client.get_value('/desktop/gnome/applications/terminal/exec')
			self.openUrl_default_terminal_arg = self.client.get_value('/desktop/gnome/applications/terminal/exec_arg')
			self.subPopen('%s %s %s %s' % (self.openUrl_default_terminal,self.openUrl_default_terminal_arg, self.openUrl_default_browser, url))
		
		#Does not need a terminal. Just call the browser with the url
		else:
			self.subPopen('%s %s' % (self.openUrl_default_browser, url))
	
	#Create the browse window for opening either a theme or theme type. Calls whatWasThat
	def browse(self):
		self.browse_win = gtk.FileChooserDialog("Select a Theme or Theme Type",action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
		self.browse_win.set_default_response(gtk.RESPONSE_OK)
		self.browse_response = self.browse_win.run()
		self.browse_filename = self.browse_win.get_filename()
		self.browse_win.destroy()
		if self.browse_response == gtk.RESPONSE_OK:
			self.whatWasThat(self.browse_filename)
		elif self.browse_response == gtk.RESPONSE_CANCEL:
			pass

		
	#This function actually imports the theme type
	#Wow this is a big function.
	def importType(self,pathname,frombrowse=True):
		from xml.dom.ext.reader.Sax2 import FromXml
		from xml.dom.ext import PrettyPrint
		if not tarfile.is_tarfile(pathname):
			self.simpleDialog("Corrupted File","The theme type file is corrupted.\nSorry.")
		else:
			#Good file!
			#So what's the point of the tarfile module again?
			
			#rm-r then mkdir /tmp/utm. cd to the dir the file is in. cp it to /tmp/utm/filename.tar.gz. cd to /tmp/utm. tar -x it there. rm filename.tar.gz
			#Some commands have > /dev/null because they might print pointless information (like if rm'ing a nonexistent directory)
			os.system('rm -r /tmp/utm')
			os.system('mkdir /tmp/utm')
			os.system('cd %s && cp %s /tmp/utm/%s && cd /tmp/utm && tar -xvvzf %s > /dev/null && rm %s' % ("/".join(pathname.split('/')[:-1]), pathname.split('/')[-1], pathname.split('/')[-1], pathname.split('/')[-1], pathname.split('/')[-1]))
			
			#Get the listing of /tmp/utm, put it in /tmp/utm2/ls.txt. Then self.import_ls = content of that.
			subprocess.Popen(['mkdir','/tmp/utm2'],stdout=open('/dev/null','w'),stderr=open('/dev/null','w')).wait()
			#os.system('mkdir /tmp/utm2 > /dev/null')
			os.system('ls -a /tmp/utm > /tmp/utm2/ls.txt')
			self.import_ls_fp = open('/tmp/utm2/ls.txt','r')
			self.import_ls = self.import_ls_fp.read()
			self.import_ls_fp.close()
			
			#Parse the listing. Split by \n. Go through each item. If it is not the current dir, parent dir, or "", add it to another list
			#That is the final file listing
			self.import_ls2 = self.import_ls.split('\n')
			self.import_ls3 = []
			for self.import_iterator in self.import_ls2:
				if self.import_iterator!=".":
					if self.import_iterator!="..":
						if self.import_iterator!="":
							self.import_ls3.append(self.import_iterator)
			
			#If no info.xml file, make dialog the file is corrupted etc.
			if not "info.xml" in self.import_ls3:
				self.simpleDialog("Corrupted File","The theme type file is corrupted.\nSorry.")
			
			#Otherwise, file is good enough! (so far)
			else:
				
				#Open info.xml. Find out the package-like-name. Go through self.typeplnames. If it's already there, dialog are you sure you want to ...
				self.import_fp = open('/tmp/utm/info.xml','r')
				self.import_doc = FromXml(self.import_fp.read())
				self.import_fp.close()
				
				#Pretty much check if the type has a package-like-name element. If not, say it's corrupted. Otherwise, continue.
				self.import_has_plname = False
				try:
					self.import_new_plname = self.import_doc.documentElement.getElementsByTagName('info')[0].getElementsByTagName('package-like-name')[0].childNodes[0].data
					self.import_has_plname = True
				except:
					self.simpleDialog("Corrupted File","The theme type file is corrupted.\nSorry.")
				
				#Now check if this is from the browse button thing. If it is, say it'll replace a type and ask if you want to continue (Dialog)
				#You are not expected to understand this. But it's pretty simple.
				self.import_continue_yet_again = True
				if self.import_has_plname==True:
					if frombrowse==True:
						if self.import_new_plname in self.typeplnames:
							for self.x in self.typeslist:
								if self.x.getAttribute('package-like-name')==self.import_new_plname:
									self.import_dialog_response = self.simpleDialog('Replace theme type?',"A theme type (\"%s\") with the keyword name of %s already exists.\nThis would mean that the file you selected will replace the \"%s\" theme type and may make the type's themes unusable. If you know you selected an upgrade to %s, click OK. Otherwise, it is recommend that you click Cancel to save the \"%s\" theme type and its themes' functionality." % (self.x.getAttribute('full-name'), self.import_new_plname, self.x.getAttribute('full-name'), self.x.getAttribute('full-name'), self.x.getAttribute('full-name')),cancel=True)
									if self.import_dialog_reponse == gtk.RESPONSE_CANCEL:
										self.import_continue_yet_again = False
					
					#We're still good (valid type so far. If it'll replace a type, either it's from checkForUpdates or user says it's ok.
					if self.import_continue_yet_again==True:
						
						#Create a type instance, then add all the attributes of the new type to the type instance
						self.import_type = Type()
						
						#Go through all the info stuff
						for self.import_x in self.import_doc.documentElement.getElementsByTagName('info')[0].childNodes:
							if self.import_x.nodeType==self.import_x.ELEMENT_NODE:
								try:
									self.import_type.addAttribute(self.import_x.nodeName,self.import_x.childNodes[0].data)
								except:
									#In case the type has <install/>,<screenshot/>, etc.
									pass
						
						#Go through all the function stuff
						for self.import_y in self.import_doc.documentElement.getElementsByTagName('functions')[0].childNodes:
							if self.import_y.nodeType==self.import_y.ELEMENT_NODE:
								try:
									self.import_type.addAttribute(self.import_y.nodeName,self.import_y.childNodes[0].data)
								except:
									pass
						
						#Now we need to find out if the new type doesn't have any of the required attributes, like full-name or import, for example
						self.import_type_ok = True
						if self.import_type.getAttribute('full-name') is None:
							self.import_type_ok = False
						if self.import_type.getAttribute('version') is None:
							self.import_type_ok = False
						if self.import_type.getAttribute('import') is None:
							self.import_type_ok = False
						if self.import_type.getAttribute('apply') is None:
							self.import_type_ok = False
						
						if self.import_type_ok == False:
							#Uh oh, it doesn't have full-name, version, import, or apply! Make that same dialog! AGAIN!
							#I really need to create a function that makes this dialog. Could save dozens of lines
							#Oh wait, I did!
							self.simpleDialog("Corrupted File","The theme type file is corrupted.\nSorry.")
							
						#OK, I think I came to the conclusion that the theme type is OK. Not corrupted, etc.
						#Almost done (I hope)
						else:
						
							#mkdir ~/.utm/type-files/package-like-name && mkdir ~/.utm/theme-files/package-like-name && themes/package-like-name
							os.system('mkdir %s/.utm/type-files/%s && mkdir %s/.utm/theme-files/%s && mkdir %s/.utm/themes/%s' % (self.homepath, self.import_new_plname, self.homepath, self.import_new_plname, self.homepath, self.import_new_plname))
							
							#Now go through the file listing, and if there are any files other than info.xml, cp it to the approiate directory
							for self.import_z in self.import_ls3:
							  if self.import_z is not "info.xml":
							  	os.system('cd /tmp/utm && cp %s %s/.utm/type-files/%s/%s' % (self.import_z, self.homepath, self.import_new_plname, self.import_z))
							

							#If the theme type has an install parameter, execute it.
							if self.import_type.getAttribute('install') is not None and self.import_type.getAttribute('install') is not "":
							    os.system(self.import_type.getAttribute('install').replace("$HOME",self.homepath).replace("~",self.homepath))
							
							#Is that it? No. Need to copy info.xml. Then add the type to ~/.utm/types.xml. Then refresh (self.viewTypesAndThemes())
							
							#Copy info.xml
							os.system('cp /tmp/utm/info.xml %s/.utm/types/%s.xml' % (self.homepath, self.import_new_plname))
							
							#Open ~/.utm/types.xml. Add the new type to it. Rewrite it.
							self.import_types_fp1 = open('%s/.utm/types.xml' % self.homepath,'r')
							self.import_types_doc = FromXml(self.import_types_fp1.read())
							self.import_types_fp1.close()
							self.import_types_doc_new_element1 = self.import_types_doc.createElement("theme-type")
							self.import_types_doc_new_element2 = self.import_types_doc.createElement("package-like-name")
							self.import_types_doc_new_textnode = self.import_types_doc.createTextNode(self.import_new_plname)
							self.import_types_doc_new_element2.appendChild(self.import_types_doc_new_textnode)
							self.import_types_doc_new_element1.appendChild(self.import_types_doc_new_element2)
							self.import_types_doc.documentElement.appendChild(self.import_types_doc_new_element1)
							self.import_types_fp2 = open('%s/.utm/types.xml' % self.homepath,'w')
							PrettyPrint(self.import_types_doc,self.import_types_fp2)
							self.import_types_fp2.close()
							
							#Remove the /tmp/utm and /tmp/utm2 directories.
							os.system('rm -r /tmp/utm')
							os.system('rm -r /tmp/utm2')
							
							#And finally... refresh.
							self.refresh()
	
	#Now for the actual function that imports a theme according to its package-like-name
	#Question: When is the data added to themes.xml??? It works though... :/
	def addTheme(self,pathname,plname):
		for self.add_x in self.typeslist:
			if self.add_x.getAttribute('package-like-name')==plname:
				os.system('cp %s ~/.utm/theme-files/%s/%s' % (pathname, plname, pathname.split('/')[-1]))
				os.system(self.add_x.getAttribute('import').replace('$HOME',self.homepath).replace('~',self.homepath).replace('%s',pathname))
				self.removeThemeDupes()
				self.refresh()
				return True
			
		return False
	
	#This function will ask the user what type of file (s)he selected. This is after clicking the "Open" button.
	def whatWasThat(self,pathname):
	
		#First, get the list of theme types. Get their plnames and their short names.
		self.what_short_names = []
		for self.what_x in self.typeslist:
			if self.what_x.getAttribute('short-name') is not None:
				self.what_short_names.append(self.what_x.getAttribute('short-name'))
			else:
				self.what_short_names.append(self.what_x.getAttribute('full-name'))
		
		#Create and show the table that everything goes in and create an iterator which will be used a lot (more than often in utm)
		self.what_table = gtk.Table(1,2,False)
		self.what_table.show()
		self.what_iterator = 0
		
		#Create and show the label ("What type of file was that?")
		self.what_label = gtk.Label("What type of file was that?")
		self.what_label.show()
		
		#Create a bigger button that spans two rows and is for a new theme type. show() attach()
		self.what_button = gtk.Button("New Theme Type")
		self.what_button.connect("clicked",lambda w: self.importType(pathname, True))
		self.what_button.connect("clicked",lambda w: self.what_dialog.destroy())
		self.what_button.show()
		self.what_table.attach(self.what_button,0,2,0,1,xoptions=gtk.SHRINK)
		
		#Now go through all the types' short names, and add a button that will add a new theme to that type. Two buttons/row
		for self.what_y in self.what_short_names:
			self.what_button = gtk.Button("%s Theme" % self.what_y)
			self.what_button.iterator = self.what_iterator
			self.what_button.connect("clicked",lambda w: sys.stdout.write("%s\n%s" % (self.typeplnames, self.what_iterator)))
			self.what_button.connect("clicked",lambda w: sys.stdout.write("\n"))
			self.what_button.connect("clicked",lambda w: self.addTheme(pathname,self.typeplnames[w.iterator]))
			self.what_button.connect("clicked",lambda w: self.what_dialog.destroy())
			self.what_button.show()
			if self.what_iterator%2==0:
				self.what_table.attach(self.what_button,0,1,(self.what_iterator+1),(self.what_iterator+2),xoptions=gtk.SHRINK)
			else:
				self.what_table.attach(self.what_button,1,2,self.what_iterator,(self.what_iterator+1),xoptions=gtk.SHRINK)
			self.what_iterator = (self.what_iterator+1)
		
		#Create the dialog with title "What was that?" with a cancel button
		self.what_dialog = gtk.Dialog("What was that?",self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
		
		#Add the "what type..." label and then the table to the dialog
		self.what_dialog.vbox.pack_start(self.what_label,False,True,5)
		self.what_dialog.vbox.pack_start(self.what_table,False,True,10)
		
		#Run() the dialog box. Destroy() when done.
		self.what_dialog.run()
		self.what_dialog.destroy()
  
  #In case a theme type did not check for duplicate themes, this one removes all but the first theme. This goes by the filename, not the name
  #So this is just for the list on the left.
	def removeThemeDupes(self):
		#Open the themes list for reading, get the doc and close
		try:
			self.dupe_fp = open('%s/.utm/themes.xml' % self.homepath,'r')
		except:
			self.dupe_fp = open('%s/.utm/themes.xml' % self.homepath,'w+')
			self.dupe_fp.write("<?xml version='1.0' encoding='utf-8'?>\n<themes />")
			self.dupe_fp.close()
			self.dupe_fp = open('%s/.utm/themes.xml' % self.homepath,'r')
		self.dupe_doc = FromXml(self.dupe_fp.read())
		self.dupe_fp.close()
		
		#Create a list for check if it is a dupe
		self.dupe_li = []
		self.dupe_li2 = []
		
		#Now go through the list of already existing themes, and if they are NOT in the list created two a few lines above, add it to the list
		for self.dupe_y in self.dupe_doc.documentElement.getElementsByTagName("theme"):
			if not self.dupe_y.getElementsByTagName("filename")[0].childNodes[0].data in self.dupe_li:
				self.dupe_li.append(self.dupe_y.getElementsByTagName("filename")[0].childNodes[0].data)
				self.dupe_li2.append(self.dupe_y.getElementsByTagName("path")[0].childNodes[0].data)
				
		
		#Now create a new xml doc
		self.dupe_doc2 = FromXml("<?xml version='1.0' encoding='utf-8'?>\n<themes />")
		
		self.dupe_iterator = 0
		#Now create an element for each theme (no duplicates this time!)
		for self.dupe_z in self.dupe_li:
			self.dupe_node1 = self.dupe_doc2.createElement("theme")
			self.dupe_node2 = self.dupe_doc2.createElement("filename")
			self.dupe_node3 = self.dupe_doc2.createTextNode(self.dupe_z)
			self.dupe_node4 = self.dupe_doc2.createElement("path")
			self.dupe_node5 = self.dupe_doc2.createTextNode(self.dupe_li2[self.dupe_iterator])
			self.dupe_node2.appendChild(self.dupe_node3)
			self.dupe_node4.appendChild(self.dupe_node5)
			self.dupe_node1.appendChild(self.dupe_node2)
			self.dupe_node1.appendChild(self.dupe_node4)
			self.dupe_doc2.documentElement.appendChild(self.dupe_node1)
			self.dupe_iterator=(self.dupe_iterator+1)
		
		#Now open the themes list for writing, then PrettyPrint() the doc to it, and close.
		self.dupe_fp = open('%s/.utm/themes.xml' % self.homepath,'w')
		PrettyPrint(self.dupe_doc2,self.dupe_fp)
		self.dupe_fp.close()
	
	#This function will clear the filter entry widget if needed
	def clearFilter(self,widgettext,force=False):
		self.filter_entry.grab_focus()
		if widgettext=="Filter..." or force==True:
			self.filter_entry.set_text("")
	
	#Displays list of repositories, and add or remove them
	def viewSources(self):
		#has to do with changing what thing is being viewed (list, get themes, get types, or view sources)
		if self.current_state=="view_sources":
			if self.changing_state == False:
				self.viewTypesAndThemes('viewSources')
		else:
			if self.current_state=="get_themes":
				self.changing_state = True
				self.get_themes.set_active(False)
				self.changing_state = False
			elif self.current_state=="get_types":
				self.changing_state = True
				self.get_types.set_active(False)
				self.changing_state = False
			self.current_state = "view_sources"
			self.filter_table.hide()
			
			self.vbox.destroy()
			
			#Create a new vbox for the left pane, show it, and add it to the scrolledwindow
			self.vbox = gtk.VBox(False,10)
			self.vbox.show()
			self.scrolled.add_with_viewport(self.vbox)
			
			#Create a table for the treeview and buttonbox
			self.viewS_table = gtk.Table(1,2)
			self.viewS_table.show()
			
			#Now create button box for add, edit, and remove source
			self.viewS_bbox = gtk.VButtonBox()
			self.viewS_bbox.set_layout(gtk.BUTTONBOX_START)
			self.viewS_bbox.show()
			
			#Add button
			self.viewS_add = gtk.Button(stock=gtk.STOCK_ADD)
			self.viewS_add.connect("clicked",lambda w:self.newSourceDialog())
			self.viewS_add.show()
			
			#Remove button
			self.viewS_remove = gtk.Button(stock=gtk.STOCK_REMOVE)
			self.viewS_remove.connect("clicked",lambda w:self.removeRepo(self.viewS_list[self.viewS_liststore[self.viewS_get_selection.get_selected()[1]].path[0]]))
			self.viewS_remove.set_sensitive(False)
			self.viewS_remove.show()
			
			#Now add the buttons to the button box
			self.viewS_bbox.add(self.viewS_add)
			self.viewS_bbox.add(self.viewS_remove)
			
			#Get the list of repositories
			self.viewS_list = self.repositories.doc.documentElement.getElementsByTagName('source')
			
			#Create the treeview and liststore for the list
			#Copied from get themes, which had the first treeview list (before that it was Tables in a VBox)
			#First, the liststore and treeview
			self.viewS_liststore = gtk.ListStore(str)
			self.viewS_treeview = gtk.TreeView(self.viewS_liststore)
			
			#text renderer for the first, and only, column
			self.viewS_textrenderer = gtk.CellRendererText()
			
			#the actual column for the information
			self.viewS_column0 = gtk.TreeViewColumn("Source")
			
			#Now add the text renderer to column 1 for information, and markup option (wow pango is awesome!)
			self.viewS_column0.pack_start(self.viewS_textrenderer,True)
			self.viewS_column0.add_attribute(self.viewS_textrenderer,'markup',0)
			
			#Now add the text column to the treeview
			self.viewS_treeview.append_column(self.viewS_column0)
			
			#Now connect() the treeview for when a row is selected
			self.viewS_get_selection = self.viewS_treeview.get_selection()
			#You are not expected to understand this next line. It just changes the right pane on selecting a row,
			#and allows the edit and remove buttons to work
			self.viewS_get_selection.connect("changed",lambda w: self.viewSourcesPane(self.viewS_list[self.viewS_liststore[w.get_selected()[1]].path[0]]))
			self.viewS_get_selection.connect("changed",lambda w: self.viewS_remove.set_sensitive(True))
			
			#Create a vseparator to make it look a little better
			self.viewS_sep = gtk.VSeparator()
			self.viewS_sep.show()
			
			#Now show the treeview, and put it and the vbuttonbox in the left pane
			self.viewS_treeview.show()
			self.viewS_table.attach(self.viewS_treeview,0,1,0,1)
			self.viewS_table.attach(self.viewS_sep,1,2,0,1,xoptions=gtk.SHRINK,xpadding=2)
			self.viewS_table.attach(self.viewS_bbox,2,3,0,1,xoptions=gtk.SHRINK)
			
			#Go through each source/repository
			for self.viewS_x in self.viewS_list:
				#Wow using a treeview uses a lot less code here
				self.viewS_content = "<big><b>%s</b></big>\n<i>%s</i>" % (self.repositories.getAttribute(self.viewS_x,'name'),\
				self.urlToHostName(self.repositories.getAttribute(self.viewS_x,'url')))
				self.viewS_liststore.append([self.viewS_content])
			
			self.vbox.pack_start(self.viewS_table)
			
			#Now create a label for the right pane (you have x source(s))
			self.viewS_label = gtk.Label("\n\n\nYou have %s source%s for themes and theme types.\n\nSelect a source on the left to\nview more information about it here.\nClick the \"Add\" button to add a new source." % (len(self.viewS_list),self.isNot1(len(self.viewS_list))))
			self.viewS_label.set_line_wrap(True)
			self.viewS_label.show()
			self.replaceRightPane(self.viewS_label)
		
	#Function that displays information about a source/repository on the right pane
	def viewSourcesPane(self,source):
		self.vsp_table = gtk.Table(3,1)
		self.vsp_name = gtk.Label(self.repositories.getAttribute(source,'name'))
		self.vsp_name.modify_font(pango.FontDescription('bold 16'))
		self.vsp_name.show()
		self.vsp_url = gtk.Label(self.repositories.getAttribute(source,'url'))
		self.vsp_url.show()
		self.vsp_type = self.repositories.getAttribute(source,'type')
		if self.vsp_type=="theme":
			self.vsp_type2 = "themes"
		elif self.vsp_type=="type":
			self.vsp_type2 = "theme types"
		else:
			self.vsp_type2 = "themes and theme types"
		self.vsp_type = gtk.Label("Contains %s." % self.vsp_type2)
		self.vsp_type.show()
		self.vsp_table.attach(self.vsp_name,0,1,0,1,xoptions=gtk.SHRINK)
		self.vsp_table.attach(self.vsp_url,0,1,1,2)
		self.vsp_table.attach(self.vsp_type,0,1,2,3)
		self.vsp_table.show()
		self.replaceRightPane(self.vsp_table)
	
	#Displays dialog for adding a new source
	def newSourceDialog(self):
		self.nsd_dialog = gtk.Dialog('Enter the repository URL.',self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK))
		self.nsd_dialog.set_size_request(300,200)
		self.nsd_dialog_label = gtk.Label("Enter the URL of the new repository.")
		self.nsd_dialog_label.show()
		self.nsd_dialog_entry = gtk.Entry()
		self.nsd_dialog_entry.connect("activate",lambda w:self.nsd_dialog.vbox.get_children()[3].get_children()[0].clicked())
		self.nsd_dialog_entry.show()
		self.nsd_dialog.vbox.pack_start(self.nsd_dialog_label,False,True,15)
		self.nsd_dialog.vbox.pack_start(self.nsd_dialog_entry,False,True,15)
		if self.nsd_dialog.run()==gtk.RESPONSE_OK:
			self.newSource(self.nsd_dialog_entry.get_text())
		self.nsd_dialog.destroy()
	
	#Function that actually adds the new repository by URL. this means wgeting it.
	def newSource(self,url):
		
		if url=="" or url.replace(" ","")=="":
			self.simpleDialog('No URL provided.','You must enter a URL of a repository.')
		
		self.ns_continue = True
		for self.ns_x in self.repositories.doc.documentElement.getElementsByTagName('source'):
			if self.repositories.getAttribute(self.ns_x,'url')==url and self.ns_continue==True:
				self.nsd_dialog.destroy()
				self.simpleDialog('Already exists.','A repository with that URL already exists.')
				self.ns_continue = False
		
		if self.ns_continue==True:
			os.system('rm -rf /tmp/utm')
			os.system('mkdir /tmp/utm')
			os.system('wget -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 --output-document=/tmp/utm/list.xml %s' % url)
		
		if not 'list.xml' in os.listdir('/tmp/utm'):
			self.simpleNetworkDialog('repository')
		
		elif self.ns_continue==True:
			try:
				
				#Add the data to the sources.xml file
				self.ns_fp = open('/tmp/utm/list.xml','r')
				self.ns_doc = FromXml(self.ns_fp.read())
				self.ns_fp.close()
				
				self.ns_new_id = self.ns_doc.documentElement.getElementsByTagName('info')[0].getElementsByTagName('id')[0].childNodes[0].data
				if self.ns_new_id in os.listdir('%s/.utm/sources' % self.homepath) or self.ns_new_id=="downloads":
					if self.ns_new_id=="downloads":
						self.ns_new_error = "The source id cannot be \"downloads\"."
					else:
						self.ns_new_error = "The source id %s is already being used.\nMake sure the id is unique, and not something like\"my-themes\"" % self.ns_new_id
					self.nsd_dialog.destroy()
					self.simpleDialog("There was an error.","There was an error in adding the repository.\nDescription: %s" % self.ns_new_error)
				
				else:
					self.ns_new_name = self.ns_doc.documentElement.getElementsByTagName('info')[0].getElementsByTagName('name')[0].childNodes[0].data
					self.ns_new_type = self.ns_doc.documentElement.getElementsByTagName('info')[0].getElementsByTagName('type')[0].childNodes[0].data
					
					self.ns_new_source_element = self.repositories.doc.createElement('source')
					
					self.ns_new_id_element = self.repositories.doc.createElement('id')
					self.ns_new_name_element = self.repositories.doc.createElement('name')
					self.ns_new_type_element = self.repositories.doc.createElement('type')
					self.ns_new_url_element = self.repositories.doc.createElement('url')
					
					self.ns_new_id_textnode = self.repositories.doc.createTextNode(self.ns_new_id)
					self.ns_new_name_textnode = self.repositories.doc.createTextNode(self.ns_new_name)
					self.ns_new_type_textnode = self.repositories.doc.createTextNode(self.ns_new_type)
					self.ns_new_url_textnode = self.repositories.doc.createTextNode(url)
					
					self.ns_new_id_element.appendChild(self.ns_new_id_textnode)
					self.ns_new_name_element.appendChild(self.ns_new_name_textnode)
					self.ns_new_type_element.appendChild(self.ns_new_type_textnode)
					self.ns_new_url_element.appendChild(self.ns_new_url_textnode)
					
					self.ns_new_source_element.appendChild(self.ns_new_id_element)
					self.ns_new_source_element.appendChild(self.ns_new_name_element)
					self.ns_new_source_element.appendChild(self.ns_new_type_element)
					self.ns_new_source_element.appendChild(self.ns_new_url_element)
					
					self.repositories.doc.documentElement.appendChild(self.ns_new_source_element)
					self.ns_fp = open('%s/.utm/sources.xml' % self.homepath,'w')
					PrettyPrint(self.repositories.doc,self.ns_fp)
					self.ns_fp.close()
					
					#Now copy and create the files/directories for this repository
					os.system('mkdir ~/.utm/sources/%s' % self.ns_new_id)
					os.system('cp /tmp/utm/list.xml ~/.utm/sources/%s/list.xml' % self.ns_new_id)
					self.ns_fp = open('%s/.utm/sources/%s/imported.xml' % (self.homepath,self.ns_new_id),'w+')
					self.ns_fp.write('<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<source-imported/>')
					self.ns_fp.close()
					os.system('echo %s > ~/.utm/sources/%s/timestamp' % (int(time.time()), self.ns_new_id))
					os.system('rm -rf /tmp/utm')
					#Done!
					self.refresh()
			
			except:
				self.simpleNetworkDialog('repository')
	
	#Function that confirms that you want to remove a repository. will NOT remove themes and theme types, but will remove the ability to update them
	def removeRepo(self,repo):
		
		#dialog to confirm deletion
		if self.simpleDialog('Are you sure?','Are you sure you want to remove the repository "%s"?\n\nRemoving a repository will NOT delete the themes and theme types you downloaded from it,\nhowever you will not be able to update the themes and theme types without manually downloading the files. Continue?' % self.repositories.getAttribute(repo,'name'),cancel=True)==gtk.RESPONSE_OK:
			for self.rmr_x in self.repositories.doc.documentElement.getElementsByTagName('source'):
				if self.repositories.getAttribute(self.rmr_x,'id')==self.repositories.getAttribute(repo,'id'):
					self.repositories.doc.documentElement.removeChild(self.rmr_x)
					self.rmr_fp = open('%s/.utm/sources.xml' % self.homepath,'w')
					PrettyPrint(self.repositories.doc,self.rmr_fp)
					self.rmr_fp.close()
					os.system('rm -r ~/.utm/sources/%s' % self.repositories.getAttribute(repo,'id'))
					self.refresh()
					return True
		return False
	
	#Function that just displays a small dialog with the provided title and text
	def simpleDialog(self,title,text,cancel=False):
		if cancel==False:
			self.sd_dialog = gtk.Dialog(title,self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK,gtk.RESPONSE_OK))
		else:
			self.sd_dialog = gtk.Dialog(title,self.w,gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK))
		self.sd_dialog_label = gtk.Label(text)
		self.sd_dialog_label.show()
		self.sd_dialog.vbox.pack_start(self.sd_dialog_label,False,True,15)
		self.sd_response = self.sd_dialog.run()
		self.sd_dialog.destroy()
		return self.sd_response
	
	#Function that calls self.simpleDialog with information about a network error (error in downloading the file, etc)
	def simpleNetworkDialog(self,filetype='theme'):
		self.simpleDialog('There was an error.',"There was an error in downloading the %s.\nThe server may be down, but you may want to check your internet connection.\nPlease try again later." % filetype)
	
	#Function that refreshes the list depending on what is shown
	def refresh(self):
		if self.current_state=="list":
			self.viewTypesAndThemes()
		elif self.current_state=="get_themes":
			self.repositories.refresh(-1)
			self.current_state = "list"
			self.getThemes()
		elif self.current_state=="get_types":
			self.repositories.refresh(-1)
			self.current_state = "list"
			self.getTypes()
		elif self.current_state=="view_sources":
			self.current_state = "list"
			self.viewSources()
			
#Note: this file used to be in its own file, and then I would have to import it. Since UTM WILL (most likely) use it no matter what, there's no point of importing.
#I really don't know what I was thinking when I wrote this file. But it was my first time with object orientation for the whole project :/
#xmlData
#Big class to handle the flat file xml stuff for ultimate-theme-manager

class xmlData:
	"""Set of functions to manipulate the xml 'database' for ultimate-theme-manager"""
	
	#Set some variables for the xmlData instance.
	def __init__(self):
		for x in os.environ.items():
			if x[0]=="HOME":
				self.homepath = x[1]
		
		self.pathToThemesDB = self.homepath+"/.utm/themes.xml"
		self.pathToTypesDB = self.homepath+"/.utm/types.xml"
	
	#Open the themes list file. Default read-only. Can be changed, e.g. pass "w+" as the first parameter to write+create if it doesn't exist
	def openThemes(self, filetype="r"):
		if filetype=="a" or filetype=="a+":
			print "This will not work correctly if you open the file for appending. Action cancelled."
		else:
			try:
				self.themesFp.close()
			except:
				pass
			try:
				self.themesFp = file(self.pathToThemesDB, filetype)
			except:
				self.themesFp = file(self.pathToThemesDB, "w+")
				self.themesFp.write("<?xml version='1.0' encoding='utf-8'?>\n<themes />")
				self.themesFp.close()
				self.themesFp = file(self.pathToThemesDB, filetype)
			return self.themesFp
	
	#Write self.themexmldoc to the themes "database".
	def writeThemes(self):
		from xml.dom.ext import PrettyPrint
		try:
			PrettyPrint(self.themexmldoc,self.themesFp)
		except:
			self.openThemes("w")
			PrettyPrint(self.themexmldoc,self.themesFp)
	
	#Return the themexmldoc and sets self.themexmldoc to an xmldocument.		
	def getThemeXmlDoc(self):
		from xml.dom.ext.reader.Sax2 import FromXml
		self.openThemes('r')
		self.themexmldoc = FromXml(self.themesFp.read())
		return self.themexmldoc
	
	#Return the exactthemexmldoc, this is the xml document of an exact theme
	def getExactThemeXmlDoc(self,themefilename):
		try:
			self.exactThemeFp.close()
		except:
			pass
		from xml.dom.ext.reader.Sax2 import FromXml
		self.exactThemeFp = open(self.homepath+'/.utm/themes/'+themefilename,'r')
		self.exactthemexmldoc = FromXml(self.exactThemeFp.read())
		return self.exactthemexmldoc
	
	#Return the Theme List as Theme()'s in a list with all their glourous attributes.
	def getThemesList(self):
		self.getThemeXmlDoc()
		
		self.li = []
		#HACK!
		for self.themesindex in self.themexmldoc.documentElement.getElementsByTagName("theme"):
			self.getExactThemeXmlDoc(self.themesindex.getElementsByTagName("filename")[0].childNodes[0].data)
			self.x = self.exactthemexmldoc.documentElement
			self.y = Theme()
			self.y.addAttribute('xml-file',self.themesindex.getElementsByTagName("filename")[0].childNodes[0].data)
			self.y.addAttribute('path',self.themesindex.getElementsByTagName("path")[0].childNodes[0].data)
			for self.z in self.x.childNodes:
				if self.z.nodeType==self.z.ELEMENT_NODE:
					try:
						self.y.addAttribute(self.z.nodeName,str(self.z.childNodes[0].data))
					except:
						self.y.addAttribute(self.z.nodeName,None)
			self.li.append(self.y)
		try:
			self.exactThemeFp.close()
		except:
			pass
		try:
			self.themesFp.close()
		except:
			pass
		return self.li
	
	#Close the themes.xml file.
	def closeThemes(self):
		try:
			self.themesFp.close()
		except:
			pass
	
	#Now done with Themes! Now for theme types!
	#I can probably copy+paste the theme code and change it to types. I'll try that.
	
	#Open the types list file. Default read-only. Can be changed, e.g. pass "w+" as the first parameter to write+create if it doesn't exist
	def openTypes(self, filetype="r"):
		if filetype=="a" or filetype=="a+":
			print "This will not work correctly if you open the file for appending. Action cancelled."
		else:
			try:
				self.typesFp.close()
			except:
				pass
			try:
				self.typesFp = file(self.pathToTypesDB, filetype)
			except:
				self.typesFp = file(self.pathToTypesDB, "w+")
				self.typesFp.write("<?xml version='1.0' encoding='utf-8'?>\n<theme-types-list />")
				self.typesFp.close()
				self.typesFp = file(self.pathToTypesDB, filetype)
			return self.typesFp
	
	#Write self.typexmldoc to the types "database".
	def writeTypes(self):
		from xml.dom.ext import PrettyPrint
		try:
			PrettyPrint(self.typexmldoc,self.typesFp)
		except:
			self.openTypes("w")
			PrettyPrint(self.typexmldoc,self.typesFp)
	
	#Return the typexmldoc and sets self.typexmldoc to an xmldocument.		
	def getTypeXmlDoc(self):
		from xml.dom.ext.reader.Sax2 import FromXml
		self.openTypes('r')
		self.typexmldoc = FromXml(self.typesFp.read())
		return self.typexmldoc
	
	#Return the Type List as Type()'s in a list with all their glourous attributes.
	def getTypesList(self):
		#Get the typexmldoc if it doesn't exist.
		self.getTypeXmlDoc()
		
		self.li = []
		for self.x in self.typexmldoc.documentElement.getElementsByTagName("theme-type"):
			self.y = Type()
			for self.z in self.x.childNodes:
				if self.z.nodeType==self.z.ELEMENT_NODE:
					self.y.byPackageLikeName(str(self.z.childNodes[0].data))
					self.li.append(self.y)
		self.typesFp.close()
		return self.li
	
	#Close the types.xml file.
	def closeTypes(self):
		try:
			self.typesFp.close()
		except:
			pass

#Just like XmlData, this used to be in its own file that needed importing. Pointless.
##!/usr/bin/env python
#
#themeClass
#Class for actual themes, so you can do things like theme.apply() and theme.getAttribute('author'), etc. I'm new to actually creating and using my own object-oriented code, so please excuse any "newbie" mistakes.

class Theme:
	"""Instead of messing with the xml stuff, use theme.getAttribute('name')! (And more!)"""
	#This sets up the attributes and values lists. I wish Python has associative arrays/lists. (Or does it?)
	def __init__(self):
		self.attributes = []
		self.values = []
	#This adds a new attribute to the theme. xmlData uses this. Returns the value. (Kinda pointless.)
	def addAttribute(self,attribute,value):
		self.attributes.append(attribute)
		self.values.append(value)
		return value
	#This changes the value of the attribute to something else. Returns the value.
	def changeAttribute(self,attribute,value):
		for self.x in self.attributes:
			if self.x==attribute:
				self.values[self.x.index(attribute)] = value
				return value
	#This gets the value of the attribute, and, yet again, returns the value.
	def getAttribute(self,attribute):
		for self.x in self.attributes:
			if self.x==attribute:
				try:
					return self.values[self.attributes.index(attribute)]
				except:
					return None

#Exact same thing as theme class, just for types, plus there's some stuff like Import, export, etc.
##!/usr/bin/env python
#
#typeClass: Instead of dealing with the types & xml stuff, just use themeType.getAttribute('version') or themeType.import(path)!
#"type" is one of those words that after say a ton of times (even in your head), it sound really weird.

class Type:
	"""Instead of messing with the xml stuff, use themeType.update()"""
	#Set some variables for the type
	def __init__(self):
		self.attributes = []
		self.values = []
		for self.x in os.environ.items():
			if self.x[0]=="HOME":
				self.homepath = self.x[1]
	
	#Add all the attributes and values by the theme type's package-like-name. (Like "avant-window-navigator" as opposed to "Awn" or "Avant W..."
	#xmlData uses this. Just in case you were wondering...
	def byPackageLikeName(self, plname):
		#plname = package-like-name
		from xml.dom.ext.reader.Sax2 import FromXmlStream
		self.fp = file(self.homepath+'/.utm/types/'+plname+'.xml','r')
		self.bpln_xmldoc = FromXmlStream(self.fp)
		self.fp.close()
		#First, all of the info elements
		for self.x in self.bpln_xmldoc.documentElement.getElementsByTagName('info')[0].childNodes:
			if self.x.nodeType==self.x.ELEMENT_NODE:
				try:
					self.addAttribute(self.x.nodeName, str(self.x.childNodes[0].data))
				except:
					pass
			
		#Now, all of the function elements (apply, export, etc.)
		for self.x in self.bpln_xmldoc.documentElement.getElementsByTagName('functions')[0].childNodes:
			if self.x.nodeType==self.x.ELEMENT_NODE:
				try:
					self.addAttribute(self.x.nodeName, str(self.x.childNodes[0].data))
				except:
					pass
	
	#Now for the addAttribute function, which should be almost, if not exactly, identical to themeClass
	def addAttribute(self,attribute, value):
		self.attributes.append(attribute)
		self.values.append(value)
		return value
	
	#Ok, it IS identical. Now for changeAttribute.
	def changeAttribute(attribute, value):
		for self.x in self.attributes:
			if self.x==attribute:
				self.values[self.x.index(attribute)] = value
				return value
	
	#And this was completely identical too. Weird. getAttribute is going to be the EXACT same.
	def getAttribute(self,attribute):
		try:
			return self.values[self.attributes.index(attribute)]
		except:
			return None
	
	#Now for export, which is NOT going to be identical to themeClass.export (because it doesn't exist!)
	def export(self):
		#Check if this type has a export function, if not print a message, otherwise, execute it.
		if self.getAttribute('export')=="":
			print "This theme type does not have an export command."
		else:
			subprocess.Popen(self.getAttribute('export').split(' '))
	
	#Returns the short name if there is one, and the longer one if there isn't
	def getShortName(self):
		if self.getAttribute('short-name') is not None:
			return self.getAttribute('short-name')
		else:
			return self.getAttribute('full-name')
	
	#Imports the theme located at path. Capital I because apparently "import" is a very valuable keyword that can't even be a function
	def Import(self,path):
		try:
			self.fp = file(path,'r')
			self.fp.close()
			self.itworked = True
		except:
			print "The file '%s' was not found." % path
			self.itworked = False
		
		#I think there's an easier way to do this. sharkbaitbobby@gmail.com colon right parentheses
		if self.itworked==True:
			subprocess.Popen(self.getAttribute('import').replace('%s',path).split(' ')).wait()
	
	#Edits the current theme. Doesn't really have to do with utm.
	def editCurrent(self):
		if self.getAttribute('edit-current')=="":
			print "This theme type has no \"edit current\" command provided."
		else:
			subprocess.Popen(self.getAttribute('edit-current').split(' '))
	
#Now a class for managing data for the repositories (lists, downloads, etc.)
class Repositories:
	"""A class for dealing with the repository stuff for Ultimate Theme Manager"""
	
	#self.doc is the sources.xml document, don't change it! (unless you're reloading)
	def __init__(self):
		for self.x in os.environ.items():
			if self.x[0]=="HOME":
				self.homepath = self.x[1]
		self.fp = open('%s/.utm/sources.xml' % self.homepath,'r')
		self.doc = FromXml(self.fp.read())
		self.fp.close()
		self.THEME_NAME = 0
		self.THEME_TYPE = 1
		self.THEME_URL = 2
		self.THEME_DESCRIPTION = 3
		self.THEME_CREDITS = 4
		self.THEME_SCREENSHOT = 5
		self.THEME_DOWNLOADS = 6
		self.THEME_SOURCE_ID = 7
		self.TYPE_NAME = 0
		self.TYPE_PACKAGE_LIKE_NAME = 1
		self.TYPE_URL = 2
		self.TYPE_DESCRIPTION = 3
		self.TYPE_CREDITS = 4
		self.TYPE_SOURCE_ID = 5
		self.TYPE_LOGO = 6
	
	#Python global variables are confusing, sets the typeplnames variable
	def setTypePlnames(self,plnames):
		self.typeplnames = plnames
	
	#A function to reload the repositories, if they haven't been seconds second(s) (default 24 hours)
	def refresh(self,seconds=86400):
		for self.x in self.doc.documentElement.getElementsByTagName("source"):
			self.fp = open('%s/.utm/sources/%s/timestamp' % (self.homepath, self.x.getElementsByTagName('id')[0].childNodes[0].data),'r')
			self.fp_content = self.fp.read()
			print self.fp_content
			print int(time.time())
			if ( ( ( int( self.fp_content ) ) + seconds ) <	int(time.time())):
				#Download is outdated...
				
				if self.x.getElementsByTagName('url')[0].childNodes[0].data[0]=="/":
					
					try:
						self.fp2 = open(self.x.getElementsByTagName('url')[0].childNodes[0].data,'r')
						self.fp2.close()
						os.system('cp %s %s/.utm/sources/%s/list.xml ' % (self.x.getElementsByTagName('url')[0].childNodes[0].data, self.homepath, self.x.getElementsByTagName('id')[0].childNodes[0].data))
					
					except:
						return "DiskError"
				
				else:
					
					os.system('wget -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 --output-document=%s/.utm/sources/downloads/%s.xml %s' % (self.homepath, self.x.getElementsByTagName('id')[0].childNodes[0].data, self.x.getElementsByTagName('url')[0].childNodes[0].data))
					
					if True:
						self.fp2 = open('%s/.utm/sources/downloads/%s.xml' % \
						(self.homepath, self.x.getElementsByTagName('id')[0].childNodes[0].data),'r')
						self.fp2_doc = FromXml(self.fp2.read())
						self.fp2.close()
						
						for self.y in self.doc.documentElement.getElementsByTagName('source'):
							if self.y.getElementsByTagName('id')[0].childNodes[0].data==self.getAttribute(self.x,'id'):
								
								self.doc.documentElement.removeChild(self.y)
								
								self.element0 = self.doc.createElement('source')
								self.element1 = self.doc.createElement('type')
								self.element2 = self.doc.createElement('url')
								self.element3 = self.doc.createElement('name')
								self.element4 = self.doc.createElement('id')
								
								self.txtnode1 = self.doc.createTextNode(self.getAttribute(\
								self.fp2_doc.documentElement.getElementsByTagName('info')[0],'type'))
								self.txtnode2 = self.doc.createTextNode(self.getAttribute(self.x,'url'))
								self.txtnode3 = self.doc.createTextNode(self.getAttribute(\
								self.fp2_doc.documentElement.getElementsByTagName('info')[0],'name'))
								self.txtnode4 = self.doc.createTextNode(self.getAttribute(\
								self.fp2_doc.documentElement.getElementsByTagName('info')[0],'id'))
								
								self.element1.appendChild(self.txtnode1)
								self.element2.appendChild(self.txtnode2)
								self.element3.appendChild(self.txtnode3)
								self.element4.appendChild(self.txtnode4)
								
								self.element0.appendChild(self.element1)
								self.element0.appendChild(self.element2)
								self.element0.appendChild(self.element3)
								self.element0.appendChild(self.element4)
								
								self.doc.documentElement.appendChild(self.element0)
								self.fp.close()
								
								self.fp = open('%s/.utm/sources.xml' % self.homepath,'w')
								PrettyPrint(self.doc,self.fp)
								self.fp.close()
						
						#Refreshes the screenshots of the themes
						for self.y in self.fp2_doc.documentElement.getElementsByTagName('item'):
							if self.getAttribute(self.y,'screenshot') is not None:
								if self.getAttribute(self.y,'screenshot').split('/')[-1:][0] != "/":
									
									self.y_img_url = self.getImagePath(self.getAttribute(self.y,'screenshot'))
									if self.y_img_url != "DownloadError":
										
										os.system('rm %s' % self.y_img_url)
										os.system('wget -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 --output-document=%s %s' % (self.y_img_url, self.getAttribute(self.y,'screenshot')))
									
						#Copy the downloaded file to the approiate place
						self.fp3 = open('%s/.utm/sources/%s/list.xml' % (self.homepath, self.getAttribute(self.x,'id')),'w')
						PrettyPrint(self.fp2_doc,self.fp3)
						self.fp3.close()
						#os.system('cp %s/.utm/sources/downloads/%s.xml %s/.utm/sources/%s/list.xml' % \
						#(self.homepath, self.getAttribute(self.x,'id'), self.homepath, self.getAttribute(self.x,'id')))
						
						#Update the timestamp file
						os.system('echo %s > %s/.utm/sources/%s/timestamp' % (int(time.time()), self.homepath, self.getAttribute(self.x,'id')))
						
						#Remove the downloaded repository (it was already copied to the approiate place)
						os.system('rm %s/.utm/sources/downloads/%s.xml' % (self.homepath, self.x.getElementsByTagName('id')[0].childNodes[0].data))
					
					else:
						print "DownloadError"
			
			try:
				self.fp.close()
			except:
				pass
	
	#A function that returns the path to the screenshot of a theme according to url.
	def getImagePath(self,url):
		self.g_fp = open('%s/.utm/sources/images.xml' % self.homepath,'r')
		self.g_doc = FromXml(self.g_fp.read())
		self.g_fp.close()
		
		for self.g_x in self.g_doc.documentElement.getElementsByTagName('image'):
			if self.getAttribute(self.g_x,'url')==url:
				return self.getAttribute(self.g_x,'path')
		
		if self.putImagePath(url) != "DownloadError":
			return self.getImagePath(url)
		else:
			return "DownloadError"
	
	#A function that adds a new value to the images.xml file, after wget'ing an image for screenshot or logo/icon (in this too)
	def putImagePath(self,url):
		
		os.system('rm -rf /tmp/utm')
		os.system('mkdir /tmp/utm')
		os.system('cd /tmp/utm && wget -nv -U "ultimate-theme-manager(.googlecode.com) (GNU wget)" --tries=1 --timeout=5 %s' % url)
		
		if True:
			self.g_fp = open('/tmp/utm/%s' % os.listdir('/tmp/utm')[0],'r')
			self.g_fp.close()
			self.g_filename = os.listdir('/tmp/utm')[0]
			self.g_didit = False
			for self.g_x in os.listdir('%s/.utm/sources/downloads/images' % self.homepath):
				if not self.g_filename in os.listdir('%s/.utm/sources/downloads/images/%s' % (self.homepath, self.g_x)):
					os.system('cp /tmp/utm/%s %s/.utm/sources/downloads/images/%s/%s' % (self.g_filename,\
					self.homepath, self.g_x, self.g_filename))
					self.g_didit = True
					break
			
			if self.g_didit==False:
				os.system('mkdir %s/.utm/sources/downloads/images/%s' % (self.homepath,\
				(len(os.listdir('%s/.utm/sources/downloads/images' % self.homepath))+1)))
				os.system('cp /tmp/utm/%s %s/.utm/sources/downloads/images/%s/%s' % (self.g_filename,\
				self.homepath, len(os.listdir('%s/.utm/sources/downloads/images' % self.homepath)), self.g_filename))
			
			os.system('rm -rf /tmp/utm')
			self.g_fp = open('%s/.utm/sources/images.xml' % self.homepath,'r')
			self.g_doc = FromXml(self.g_fp.read())
			self.g_fp.close()
			
			self.g_element0 = self.g_doc.createElement('image')
			self.g_element1 = self.g_doc.createElement('url')
			self.g_element2 = self.g_doc.createElement('path')
			
			self.g_txtnode1 = self.g_doc.createTextNode(url)
			self.g_txtnode2 = self.g_doc.createTextNode('%s/.utm/sources/downloads/images/%s/%s' % (self.homepath, len(os.listdir('%s/.utm/sources/downloads/images' % self.homepath)), self.g_filename))
			
			self.g_element1.appendChild(self.g_txtnode1)
			self.g_element2.appendChild(self.g_txtnode2)
			
			self.g_element0.appendChild(self.g_element1)
			self.g_element0.appendChild(self.g_element2)
			
			self.g_doc.documentElement.appendChild(self.g_element0)
			
			self.g_fp = open('%s/.utm/sources/images.xml' % self.homepath,'w')
			PrettyPrint(self.g_doc,self.g_fp)
			self.g_fp.close()
		
		else:
			return "DownloadError"
		
	#A simple function that returns the a certain attribute of the provided part of an xml document
	def getAttribute(self,doc,attribute):
		try:
			return doc.getElementsByTagName(attribute)[0].childNodes[0].data
		except:
			return None
	
	#Now a function to get a list of theme types, good to store then parse by filter (maybe)
	def getTypes(self):
		self.li = []
		self.iterator = 0
		for self.x in self.doc.documentElement.getElementsByTagName('source'):
			if self.getAttribute(self.x,'type')=="type" or self.getAttribute(self.x,'type')=="both":
				self.t2_fp = open('%s/.utm/sources/%s/list.xml' % (self.homepath, self.getAttribute(self.x,'id')),'r')
				self.t2_doc = FromXml(self.t2_fp.read())
				self.t2_fp.close()
				for self.y in self.t2_doc.documentElement.getElementsByTagName('item'):
					if self.getAttribute(self.y,'type')=="type":
						self.li.append([\
						self.getAttribute(self.y,'name'),\
						self.getAttribute(self.y,'package-like-name'),\
						self.getAttribute(self.y,'url'),\
						self.getAttribute(self.y,'description'),\
						self.getAttribute(self.y,'credits'),\
						self.getAttribute(self.x,'id'),\
						self.getAttribute(self.y,'logo')])
			self.iterator=(self.iterator+1)
		return self.li
			
	#Now a function to get a list of themes
	def getThemes(self):
		self.li = []
		for self.x in self.doc.documentElement.getElementsByTagName('source'):
			if self.getAttribute(self.x,'type')=="theme" or self.getAttribute(self.x,'type')=="both":
				self.fp2 = open('%s/.utm/sources/%s/list.xml' % (self.homepath, self.getAttribute(self.x,'id')),'r')
				self.doc2 = FromXml(self.fp2.read())
				self.fp2.close()
				for self.y in self.doc2.documentElement.getElementsByTagName('item'):
					if self.getAttribute(self.y,'type')=="theme":
						if self.getAttribute(self.y,'theme-type') in self.typeplnames:
							self.li.append([\
								self.getAttribute(self.y,'name'),\
								self.getAttribute(self.y,'theme-type'),\
								self.getAttribute(self.y,'url'),\
								self.getAttribute(self.y,'description'),\
								self.getAttribute(self.y,'credits'),\
								self.getAttribute(self.y,'screenshot'),\
								self.getAttribute(self.y,'downloads'),\
								self.getAttribute(self.x,'id')])
		return self.li
						
	#Now a function for getting the attribute of a repository (by id)
	def getRepoAttribute(self,repoid,attribute):
		for self.x in self.doc.documentElement.getElementsByTagName('source'):
			if self.getAttribute(self.x,'id')==repoid:
				return self.getAttribute(self.x,attribute)
	
#Is that it?
#No, I have to make sure that the Pope is Catholic

if __name__ == "__main__":
	if the_pope is catholic:
		m = mainWindow()
